1

I recently converted a VB6 program to VB.NET. This program is used to communicate with the Superlogics PCM Series DAQ card that the company no more produces and has no support for VB.NET. My program was running fine in VB6 but has problems in VB.net due to the the functions in the external .dll file (I am not sure though)

I read many forums and did some changes with respect to the marshaling attributes. So guys please give me your ideas to solving this -

Error

'I am getting an error with intStatus = 350 (referring to "Invalid Request Handle")

'The superlogics manual just asks me to check the PCMDigitalInputVB function. Please help me, Thanks in advance

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

'I am getting an error saying that "Invalid Request Handle" with intStatus = 350

'The superlogics manual asks me to check the PCMDigitalInputVB function and nothing more '-------------------------------------------------------------------

    intStatus = PCMDigitalInputVB(LogicalDevice, udtDigioRequest, intRequestHandle)


End Function

'-----Function Declaration'---------------

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

'------------ Structure declaration -----------------------------------------

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
4

2 回答 2

1

由于 VB6 代码工作正常,我只需在 VB6 类模块中转换(包装)相关接口代码并创建一个 COM 组件(在 VB6 中新建项目> ActiveX DLL)。
可以使用 COM 互操作从 .NET 调用生成的 COM DLL。
有关更多详细信息,另请参阅此 SO 问题

于 2010-10-20T05:37:39.553 回答
0

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

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

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

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

于 2010-10-20T06:00:43.923 回答