Bonjour,
Dans un projet en C#, j'utilise des fonctions qui sont dans des DLL écrites en C dont j'ai le prototype.
J'ai un crash "'PInvokeStackImbalance' " lorsque j'utilise l'une des fonction: dbClassAttach.
Son prototype C est
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 HCLASS far pascal dbClassAttach(HSESS hSess, long objclass);
La déclaration C# de cette fonction est:
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 [DllImport("crdbapi.dll")] public static extern crc.HCLASS dbClassAttach(crc.HSESS hSess, long objclass);
HCLASS et HSESS en C/C++ (crc.HSESS crc.HSESS en C#) sont des types construits : un pointer sur un void: void* que j'ai défini en C# comme ca dans un classe nommée crc:
(Le mode unsafe permettant au compilateur de prendre en compte les pointeurs)
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 unsafe public struct HSESS { public void* hSess; } unsafe public struct HCLASS { public void* hClass; }
J'appelle la fonction comme ca:
Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 crc.HCLASS hClass = dbClassAttach(GlobalVar.hSess, 1);
où le type crc.HCLASS hClass est défini plus haut. La variable GlobalVar.hSess est de type HSESS, comme défini plus haut (un pointeur sur un void). Ce GlobalVar.hSess est l'identifiant de session ouverte par une autre fonction (dbSessLoginServer) qui fonctionne, elle, parfaitement et sans aucun problème.
Tous cela me parait cohérent et la conversion des types C vers C# me semble OK. Pourtant, j'ai l'erreur 'PInvokeStackImbalance' ".
Le texte d'erreur exact est le suivant:
"
L'Assistant Débogage managé 'PInvokeStackImbalance' a détecté un problème dans 'C:\MyData\XXXX\Eng\C#\XXXX\MySNMPcConsole\bin\Debug\XXXX.vshost.exe'.
Informations supplémentaires*: Un appel à la fonction PInvoke 'XXXX!XXXX.Main::dbClassAttach' a déséquilibré la pile. Cela peut se produire, car la signature PInvoke managée ne correspond pas à la signature cible non managée. Vérifiez que la convention d'appel et les paramètres de la signature PInvoke correspondent à la signature non managée cible.
"
Je comprends que la façon dont j'appelle la fonction avec ses arguments (signature/prototype) (ou en réalité la déclaration de la DLL avec le DLLImport) n'est pas la même que celle défini dans la DLL (code non managé) . Alors que j'ai respecté la définition du header.h C.
Une idée ? Est-ce que c'est moi qui ne fait pas les choses comme il faudrait ?
Autre question: on peut lister toutes les fonctions d'une DLL, il existe des trucs que j'ai essayés. Mais Est-ce que il existe des choses pour extraire la signature des fonctions présentes dans la DLL ? Ou si c'est impossible ?
Merci.
Partager