2010-10-20 7 views
1

J'ai récemment converti un programme VB6 à VB.NET. Ce programme est utilisé pour communiquer avec la carte DAQ Superlogics PCM Series que l'entreprise ne produit plus et n'a aucun support pour VB.NET. Mon programme fonctionnait bien dans VB6 mais a des problèmes dans VB.net en raison des fonctions dans le fichier .dll externe (je ne suis pas sûr cependant)Problème de conversion VB6 vers VB.NET, appel de fonction à une fonction .dll renvoie une erreur

J'ai lu beaucoup de forum et ai fait quelques changements en ce qui concerne les attributs de marshaling . Alors les gars s'il vous plaît donnez-moi vos idées pour résoudre ce -

Erreur

« Je reçois une erreur intStatus = 350 (en référence à « Poignée de demande non valide »)

» La Le manuel de superlogics me demande simplement de vérifier la fonction PCMDigitalInputVB. S'il vous plaît aidez-moi, Merci à l'avance

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 

« Je reçois une erreur disant que « Poignée de demande non valide » avec intStatus = 350

» Le manuel superlogics me demande de vérifier la fonction PCMDigitalInputVB et rien de plus '------------------------------------------------ -------------------

intStatus = PCMDigitalInputVB(LogicalDevice, udtDigioRequest, intRequestHandle) 


End Function 

'----- Déclaration de fonction' ---------------

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

'------------ Déclaration de structure ------------------------------ -----------

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 

Répondre

1

Depuis le code VB6 fonctionne bien comme il est, je voudrais juste convertir (wrap) le code d'interface pertinente dans un module de classe VB6 et créer un composant COM (Nouveau projet > DLL ActiveX dans VB6).
La DLL COM qui en résulte peut être appelée à partir de .NET à l'aide de COM Interop. Voir aussi this SO question pour plus de détails.

+0

renick, merci pour votre lien ... le pdf est utile. Mais ma première chose serait d'installer VS2008 b'coz le pdf me demande de créer une application ASP.NET et j'utilisais l'édition VB 2008 Express jusqu'à maintenant.Aussi, pensez-vous que je peux transférer la DLL générée par VB6 dans un ordinateur vers un autre ordinateur et travailler à partir de là pour VB.NET? – Naveen

+0

Oui, vous pouvez construire dll sur un ordinateur différent. – MarkJ

+0

COM Interop fonctionne dans tout type de projet. Je suppose que cela fonctionne aussi dans les éditions express. La DLL com fonctionne dans n'importe quelle machine Windows de 2K/XP à Win7 tant que ses dépendances sont présentes (c'est-à-dire le runtime VB6 et la DLL de votre interface DAQ). Si vous le déplacez sur une autre machine, vous devez l'enregistrer (google: 'regsvr32') car il s'agit d'une DLL COM. – renick

0

Cela ressemble à un problème pInvoke. Ceux-ci peuvent être assez frustrants. Comme l'a dit le commentateur précédent, il vous sera peut-être plus facile d'envelopper votre code existant dans un composant VB6 COM et de l'appeler depuis votre projet dotNet. Cependant, cela devrait également être possible à partir de dotNet. Une chose à garder à l'esprit est le garbage collector. Toute variable (y compris UDT/structs) peut être déplacée en mémoire par le garbage collector à tout moment. Généralement, cela se manifeste comme l'application fonctionne parfois, mais pas d'autres fois. Si l'erreur se produit à chaque fois, vérifiez vos déclarations pInvoke pour les appels API et vérifiez que vous utilisez les types et tailles de données corrects. Assurez-vous également de transmettre les paramètres byval/byref de manière appropriée. Par ailleurs, il est difficile de diagnostiquer ces problèmes sans avoir accès à la documentation de l'API ou à beaucoup d'essais et d'erreurs.

+0

Zippit, Maintenant, j'essaie d'en apprendre davantage sur les problèmes de pInvoke. Merci pour le lead – Naveen

Questions connexes