VB6转VB.NET转换问题,函数调用.dll函数返回错误

时间:2010-10-20 05:07:30

标签: vb6 vb6-migration

我最近将VB6程序转换为VB.NET。该程序用于与公司不再生产且不支持VB.NET的Superlogics PCM系列DAQ卡进行通信。我的程序在VB6中运行正常但由于外部.dll文件中的函数而在VB.net中出现问题(我不确定)

我阅读了很多论坛,并对编组属性进行了一些更改。那么伙计们请你解决这个想法 -

错误

'我收到的错误是intStatus = 350(指“无效的请求句柄”)

'superlogics手册要求我检查PCMDigitalInputVB函数。请帮助我,提前致谢

Public Function singleDigitalInput(ByVal LogicalDevice As Short, ByVal Channel As Short, ByRef InputValue As Byte) As Long

    Dim intStatus As Short
    Dim intRequestHandle As Short
    Dim udtDigioRequest As New DigioRequest
    udtDigioRequest.Initialize()
    Dim udtDataBuffer As New PCMDriveBuffer
    Dim udtAllocateRequest As New allocate_request

    Dim lngRetChannelAdd As Integer
    Dim lngRetBufferAdd As Integer

    Dim blnCompleteStatus As Boolean
    Dim lngEventMask As Integer
    Dim ErrorCode As Short

    On Error GoTo errUnknown



    intRequestHandle = 0
    blnCompleteStatus = False

    '-------------------------------------------------------------------
    'Allocate and lock memory for the Digital Input
    '-------------------------------------------------------------------

    With udtAllocateRequest
        .request_type = DIGIN_TYPE_REQUEST
        .channel_array_length = 1
        .number_of_buffers = 1
        .buffer_size = 1
        .buffer_attributes = RING_BUFFER
    End With

    intStatus = PCMAllocateRequestVB(LogicalDevice, udtAllocateRequest)

    If intStatus <> 0 Then
        singleDigitalInput = intStatus
        Exit Function
    End If

    'Debug.Print "Allocate Request Status = " & intStatus

    '-------------------------------------------------------------------
    'Prepare the Digital Input Request Structure
    '-------------------------------------------------------------------

    lngRetChannelAdd = PCMGetAddressOfVB(Channel)
    'UPGRADE_WARNING: Couldn't resolve default property of object udtDataBuffer. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="6A50421D-15FE-4896-8A1B-2EC21E9037B2"'
    lngRetBufferAdd = PCMGetAddressOfVB(udtDataBuffer)

    With udtDigioRequest
        .ChannelArrayPtr = lngRetChannelAdd
        .ArrayLength = 1
        .DigioBufferptr = lngRetBufferAdd
        .NumberOfScans = 1
        .IOMode = ForegroundCPU
        .TriggerSource = InternalTrigger
        .ScanEventLevel = 0
        .RequestStatus = NoEvents
    End With

    '-------------------------------------------------------------------
    'Send a digital input request to the PCMDrive

'我收到错误,说“无效请求句柄”,intStatus = 350

'超级逻辑手册要求我检查PCMDigitalInputVB功能,仅此而已         “------------------------------------------------- ------------------

    intStatus = PCMDigitalInputVB(LogicalDevice, udtDigioRequest, intRequestHandle)


End Function

'-----功能声明'---------------

Declare Function PCMDigitalInputVB Lib "PCMDrvVB.DLL" (ByVal logical_device As Short, ByRef Request As DigioRequest, ByRef handle As Short) As Short

'------------结构声明-------------------------------- ---------

Structure DigioRequest
    Dim ChannelArrayPtr As Integer ' address of channel scan list
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim ReservedArray0 As Short() ' reserved for future expansion
    Dim ArrayLength As Short ' length of chan & gain arrays
    Dim DigioBufferptr As Integer ' address of PCMDRIVE_buffer
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim ReservedArray1 As Short() ' reserved for future expansion
    Dim TriggerSource As Short ' trigger source
    Dim TriggerMode As Short ' continuous / one-shot trigger
    Dim TriggerSlope As Short ' rising / falling edge trigger
    Dim TriggerChannel As Short ' trigger channel number
    '   (analog or digital trigger)
    Dim TriggerVoltage As Double ' trigger voltage (analog trigger)
    Dim TriggerValue As Integer ' value for trigger (digital trigger)
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim ReservedArray2 As Short() ' reserved for future expansion
    Dim IOMode As Short ' input mode
    '    = 0 poll
    '    = 1 IRQ
    '    = 2 DMA with CPU status
    '    = 3 DMA with IRQ status
    Dim ClockSource As Short ' clock source (0 = internal)
    Dim ClockRate As Double ' clock rate (if not internal)
    Dim SampleRate As Double ' input sampling rate (Hz)
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim ReservedArray3 As Short() ' reserved for future expansion
    Dim NumberOfScans As Integer ' number of channel scans
    Dim ScanEventLevel As Integer ' generate event each scan_event_level
    '    scans ( 0 = disable )
    <MarshalAs(UnmanagedType.ByValArray, SizeConst:=7)> Dim ReservedArray4 As Short() ' reserved for future expansion
    Dim TimeoutInterval As Short ' timeout interval (in sec)
    Dim RequestStatus As Integer ' request event status
    Public Sub Initialize()
        ReDim ReservedArray0(3)
        ReDim ReservedArray1(3)
        ReDim ReservedArray2(3)
        ReDim ReservedArray3(3)
        ReDim ReservedArray4(7)
    End Sub
End Structure

2 个答案:

答案 0 :(得分:1)

由于VB6代码工作正常,我只是转换(包装)VB6类模块中的相关接口代码并创建COM组件(VB6中的新项目&gt; ActiveX DLL)。 可以使用COM Interop从.NET调用生成的COM DLL 有关详细信息,另请参阅this SO question

答案 1 :(得分:0)

这看起来像是一个pInvoke问题。这些可能非常令人沮丧。正如之前的评论者所说,您可能更容易将现有代码包装到VB6 COM组件中并从dotNet项目中调用它。

然而,它也应该是dotNet可行的。要记住的一件事是垃圾收集器。任何变量(包括UDT /结构)都可以随时由垃圾收集器在内存中移动。通常,这会表现为应用程序有时工作,但不会在其他时间工作。

如果每次都发生错误,请仔细检查API调用的pInvoke声明,并确保使用正确的数据类型和大小。还要确保适当地传递参数byval / byref。

除此之外,如果不访问API文档或大量试错,很难诊断这些问题。