VB6 to VB.NET conversion issues, .dll function returns an error

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Naveen Bibinaga
    New Member
    • Oct 2010
    • 5

    VB6 to VB.NET conversion issues, .dll function returns an error

    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)

    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", please refer Line 73 in the program

    'The superlogics manual asks me to check the PCMDigitalInput VB function and nothing more

    Please guide me to the cause, Thanks in advance



    Code:
     
    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
    
    [B]'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)
    [/B]
    
    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
            '-------------------------------------------------------------------
     <StructLayout(LayoutKind.Sequential, Pack:=1)> 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
    
            'UPGRADE_TODO: "Initialize" must be called to initialize instances of this structure. Click for more: 'ms-help://MS.VSCC.v90/dv_commoner/local/redirect.htm?keyword="B4BFF9E0-8631-45CF-910E-62AB3970F27B"'
            Public Sub Initialize()
                ReDim ReservedArray0(3)
                ReDim ReservedArray1(3)
                ReDim ReservedArray2(3)
                ReDim ReservedArray3(3)
                ReDim ReservedArray4(7)
            End Sub
    End Structure
  • !NoItAll
    Contributor
    • May 2006
    • 297

    #2
    Just guessing here but you might try changing InRequestHandle from SHORT to either Integer or IntPtr...

    Comment

    • Naveen Bibinaga
      New Member
      • Oct 2010
      • 5

      #3
      Thanks for your reply. I checked with both of the data types but no luck so far.

      Comment

      • !NoItAll
        Contributor
        • May 2006
        • 297

        #4
        Ok - are you passing IntRequestHandl e as a parameter to get the return value in that variable - or are you supposed to be passing in a valid handle? Looking at your code it looks like IntRequestHandl e is set to 0 when you pass it in - and I imagine that would be an invalid handle if the function is looking for an existing handle. It would appear that you have to provide a valid handle to the process for which you are checking status rather then passing in 0.
        Maybe, however IntRequestHandl e returns a handle you use later on - it's not clear to me.

        Comment

        • Naveen Bibinaga
          New Member
          • Oct 2010
          • 5

          #5
          I crosschecked with the DAQ card manual and here is the explanation-
          PCMDigitalInput performs the configuration portion of a digital input request. For a new configuration,
          the application program sets request_handle to 0 before calling PCMDigitalInput . PCMDigitalInput
          then analyzes the data structure specified by user_request to determine if all of the parameters are valid and if the requested operation can be performed by the device specified by logical_device. If the
          requested operation is valid, PCMDigitalInput assigns request_handle a unique non-zero value. This
          request handle is used to identify this request in all future operations.


          And about the error code 150 -

          150 Invalid request handle.
          A request could not be found with the specified request handle. Make sure the configuration procedure (PCMAnalogInput , PCMAnalogOutput , PCMDigitalInput , or PCMDigitalOutpu t) executed successfully and that the request handle matches the value returned by the configuration procedure

          Comment

          • !NoItAll
            Contributor
            • May 2006
            • 297

            #6
            Well, That all seems confusing. The error (150) is indicating it got a handle it didn't like for a call that is supposed to return a handle.
            Ok - another tack...
            Your instantiation of the function looks too VB6ish to me...
            Code:
            Declare Function PCMDigitalInputVB Lib "PCMDrvVB.DLL" (ByVal logical_device As Short, ByRef Request As DigioRequest, ByRef handle As Short) As Short
            seems like it needs proper decoration.

            Try:
            Code:
            <DLLImport("PCMDrvVB.DLL", SetLastError:=True, CharSet:=CharSet.Auto)> _
            Private Function PCMDigitalInputVB(ByVal logical_device As IntPtr, ByRef Request As DigioRequest, ByRef handle As IntPtr) As IntPtr
            End Function
            I changed your Shorts to IntPtr - but you might try Integer, Long, Short - it's never clear how data types are handled and returned in external DLLs.

            Comment

            • Naveen Bibinaga
              New Member
              • Oct 2010
              • 5

              #7
              Thank you!...I will try and keep you updated

              Comment

              • Naveen Bibinaga
                New Member
                • Oct 2010
                • 5

                #8
                I tried all the data types and no luck still....
                But I would like to point you to this specific function through which I get the address of the variable, that I pass to "PCMDigitalInpu tVB" function

                Code:
                lngRetBufferAdd = PCMGetAddressOfVB(channel)
                **************D eclaration***** *****
                Code:
                Declare Function PCMGetAddressOfVB Lib "PCMDrvVB.DLL" (ByRef pointer As Integer) As Integer

                Do you think, the returned addresses are right? How do I check? This is the only thing I want to clarify.

                I think you are right, its never clear how data types are handled in external Dll. I am breaking my head on this for the past 3 days. Now, I should probably start coding in C, this DAQ card also supports "C". Do you have any more suggestions?

                I appreciate all your help.
                Last edited by Naveen Bibinaga; Oct 21 '10, 04:06 AM. Reason: adding further details

                Comment

                • !NoItAll
                  Contributor
                  • May 2006
                  • 297

                  #9
                  I don't see the value in getting the address since the DLL appears to have named entry points you are supposed to be able to use.
                  I guess I'm out of ideas now too. Have you tried contacting the company to see if they have any knowledge of how to use their libs in vb.net?
                  Also - is their c lib also a dll? You actually may have more luck marshaling the functions from that dll in vb.net then trying to use the lib made for vb6. I would think it would be much the same as using win32 APIs.

                  Comment

                  Working...