views:

39

answers:

2

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
+1  A: 

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.

renick
renick, thanks for your link...the pdf is helpful. But my first thing would be to install VS2008 b'coz the pdf asks me to create ASP.NET application and I was using VB 2008 express edition till now. Also, do you think I can transfer the VB6 generated dll in one computer to another computer and work from there for VB.NET?
Naveen
Yes, you could build dll on different computer.
MarkJ
The COM Interop works in any kind of project. I assume it also works in express editions. The com DLL works in any windows machine from 2K/XP to Win7 as long as its dependencies are present(i.e. VB6 runtime and your DAQ interface DLL). If you move it to another machine you need to register it (google: 'regsvr32') because it is a COM DLL.
renick
I have been working for the whole yesterday, solved many errors due to GoTo and End statements in the ActiveX Dll file, but when I am calling a function int the dll file, I'm getting the "error 424: object required"
Naveen
I'm now thinking, may be I should just leave this VB.NET conversion and just code in "C" and get going. By the way, this DAQ card also supports "C" with associated header files.
Naveen
C++ will be the final solution. And you get rid of COM if you go the C++/CLI way with a mixed assembly (native and managed code together)
renick
However before giving up try first to use your component from VB6. If it works then it is a registration issue. Note that every time you build the component on the VB6 side you need to drop and add the reference again in VB.NET (because every build changes the COM GUIDs).
renick
A: 

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.

Zippit
Zippit, Now I am trying to learn about pInvoke issues. Thanks for the lead
Naveen