VB6 to VB.NET conversion issue, function call to a .dll function returns an error
I recently convert开发者_如何学Ced 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
Since the VB6 code works fine as is I would just convert(wrap) the relevant interfacing code in a VB6 class module and create a COM component (New Project > ActiveX DLL in VB6).
The resulting COM DLL can be called from .NET using COM Interop.
See also this SO question for more details.
This looks like an pInvoke issue. These can be quite frustrating. As the previous commenter said, it might be easier for you just to wrap your existing code into a VB6 COM component and call that from your dotNet project.
However, it should be doable from dotNet as well. One thing to keep in mind is the garbage collector. Any variable (including UDT/structs) can be moved in memory by the garbage collector at any time. Typically this will manifest itself as the app working sometimes, but not other times.
If the error occurs every time then double check your pInvoke declarations for the API calls and make sure you are using the correct data types and sizes. Also make sure you are passing parameters byval/byref appropriately.
Other then that it is difficult to diagnose these issues without access to the API documentation or lots of trial and error.
精彩评论