2010-01-15 9 views
2

J'ai une DLL pour une classe C++ (SLABHIDDevice.dll). J'essaie d'utiliser les fonctions de cette DLL dans une application C# .net. Le dll contient plusieurs méthodes que je peux utiliser facilement avec des déclarations telles que ce ...Utilisation de DLLImport pour importer un objet

(j'appolagize si je reçois une partie de la terminologie que je me trompe de nouveau à l'aide de dll)

[DllImport("SLABHIDDevice.dll")] 
     public static extern byte GetHidString 
      (Int32 deviceIndex, Int32 vid, Int32 pid, 
      Byte hidStringType, String deviceString, 
      Int32 deviceStringLength); 

La documentation pour SLABHIDDevice.dll dit qu'il contient également un objet de classe, CHIDDevice. et cet objet a toute une liste de fonctions membres telles que Open();

Si j'essaie d'importer Open() en utilisant la même syntaxe que ci-dessus, j'obtiens une erreur disant qu'il ne peut pas trouver un point d'entrée pour la fonction Open(). Est-ce parce que Open() est membre de CHIDDevice?

C'est le maquillage de la DLL de DUMPBIN ... Les trois fonctions du bas sont les seules que je suis capable de travailler? Est-ce que quelqu'un sait quelle syntaxe j'ai besoin d'utiliser pour obtenir les autres? Que signifient les points d'interrogation qui précèdent les noms des fonctions?

Dump of file SLABHIDDEVICE.dll 

File Type: DLL 

    Section contains the following exports for SLABHIDDevice.dll 

    00000000 characteristics 
    47E13E0F time date stamp Wed Mar 19 12:23:43 2008 
     0.00 version 
      1 ordinal base 
      26 number of functions 
      26 number of names 

    ordinal hint RVA  name 

      4 0 00001000 [email protected]@[email protected]@@Z 
      5 1 00001330 [email protected]@[email protected] 
      6 2 00001430 [email protected]@[email protected] 
      7 3 00001080 [email protected]@[email protected]@@Z 
      8 4 00020044 [email protected]@[email protected] 
      9 5 00001460 [email protected]@@QAEEXZ 
     10 6 00001C70 [email protected]@@QAEHXZ 
     11 7 00001CA0 [email protected]@@QAEGXZ 
     12 8 00001850 [email protected]@@[email protected] 
     13 9 00001C80 [email protected]@@QAEGXZ 
     14 A 00001BE0 [email protected]@@[email protected] 
     15 B 00001A20 [email protected]@@[email protected] 
     16 C 00001CB0 [email protected]@@QAEKXZ 
     17 D 00001C90 [email protected]@@QAEGXZ 
     18 E 00001730 [email protected]@@[email protected] 
     19 F 00001CC0 [email protected]@@[email protected] 
     20 10 00001700 [email protected]@@QAEHXZ 
     21 11 000014A0 [email protected]@@[email protected] 
     22 12 00001360 [email protected]@@AAEXXZ 
     23 13 00001810 [email protected]@@[email protected] 
     24 14 00001B80 [email protected]@@[email protected] 
     25 15 000018C0 [email protected]@@[email protected] 
     26 16 00001CE0 [email protected]@@[email protected] 
      3 17 00001320 GetHidGuid 
      2 18 000GetHidString 
      1 19 00001190 GetNumHidDevices 

    Summary 

     6000 .data 
     7000 .rdata 
     5000 .reloc 
     4000 .rsrc 
     1C000 .text 

Répondre

3

Vous ne pouvez pas utiliser P/Invoke pour appeler les méthodes d'instance d'une classe C++. Le raccrochage principal est que vous ne pouvez pas créer un objet de la classe, vous ne pouvez pas découvrir la taille d'allocation de mémoire requise. Passer le pointeur implicite "this" à la méthode d'instance est un autre problème, il doit être passé dans un registre.

Vous devez créer un wrapper géré pour la classe, qui nécessite l'utilisation du langage C++/CLI. Google "C++/CLI wrapper" pour de bons résultats.

+0

Passer 'this' n'est pas un problème car il y a' CallingConvention.ThisCall' (qui est compatible avec VC++, au moins). Le côté allocation de mémoire requis peut être déterminé si des en-têtes sont disponibles pour la DLL (et ils devraient l'être, sinon personne ne pourrait l'utiliser à partir de C++). –

+0

Hmm, je ne sais pas comment le compilateur C# va analyser cet en-tête. –

1

C++ utilise le nom mangling. Tous les symboles bizarres autour de vos noms de fonctions sont un moyen pour le compilateur/éditeur de liens de connaître la convention d'appel, les paramètres, le type de retour, etc.

Si vous ne voulez pas utiliser le nom mangling avec vos fonctions, vous devez entourez-les d'un

extern "C" { 
} 

déclaration.

Voir http://en.wikipedia.org/wiki/Name_mangling