2009-05-31 4 views
0

J'essaie d'appeler certaines fonctions dans une DLL compilée avec (je crois) Visual C++ à partir de mon programme, qui est compilé en utilisant GCC.Problèmes de pile lors de l'appel d'une DLL compilée avec Visual C++ dans GCC

Pour appeler les fonctions dans la DLL, je fais un LoadLibrary() sur la DLL, puis un GetProcAddress() pour obtenir l'adresse d'une fonction particulière, que j'appelle alors. Cette fonction renvoie une liste de pointeurs vers les fonctions de la DLL que je dois appeler.

Eh bien, quand j'essaie d'appeler ces fonctions, elles ne fonctionnent pas correctement. J'ai exécuté mon programme par l'intermédiaire d'un débogueur, et il semble que la fonction de bibliothèque DLL recherche l'un des arguments passés à ebp + 8, même si GCC l'a mis à ebp-24.

Cela ressemble vraiment à un problème de pile. De plus, lorsque la fonction du programme GCC qui appelle la fonction DLL revient, mon programme se bloque - donc quelque chose de visqueux se passe avec la pile. Est-ce que quelqu'un sait ce que je dois faire pour résoudre ce problème? Je ne suis pas en mesure d'accéder au code DLL.

Également: J'ai essayé de mettre __cdecl et __stdcall avant la définition de la fonction DLL dans le fichier source de mon programme, mais cela ne change rien.

Répondre

2

Cela ressemble à un problème de convention d'appel. Assurez-vous de placer la balise de convention d'appel au bon endroit. Avec GCC, il devrait ressembler à ceci:

typedef int (__stdcall *MyFunctionType)(int arg1, const char *arg2); 
MyFunctionType myFunction = (MyFunctionType)GetProcAddress(myModule, "MyFunction"); 
// check for errors... 
int x = myFunction(3, "hello, world!"); 

[EDIT]

On dirait que votre problème n'a rien à voir avec les conventions d'appel (bien que leur droit d'obtenir est important). Vous utilisez abusivement BSTR s - un BSTR est pas un simple pointeur char*. C'est un pointeur vers une chaîne Unicode (wchar_t*), et de plus, il y a un préfixe de longueur de 4 octets caché avant les premiers caractères de la chaîne. Voir MSDN pour plus de détails. Donc, l'appel à SetLicense() devrait ressembler à ceci:

BSTR User = SysAllocString(L""); // Not sure if you can use the same object here, 
BSTR Key = SysAllocString(L""); // that depends on if SetLicense() modifies its 
            // arguments; using separate objects to be safe 
// check for errors, although it's pretty unlikely 
(textCapLib.sdk)->lpVtbl->SetLicense((textCapLib.sdk), User, Key); 
SysFreeString(User); // Hopefully the SDK doesn't hang on to pointers to these 
SysFreeString(Key); // strings; if it does, you may have to wait until later to 
         // free them 
+0

Merci pour la réponse. Malheureusement, c'est exactement ce à quoi cela ressemble dans le fichier d'en-tête C. Existe-t-il autre chose de différent entre comment VC++ compile le code et comment compile-t-il le code? Stack alignement, ou ...? Juste une note; Dans le fichier d'en-tête de la bibliothèque, il est dit que les paramètres du compilateur étaient les suivants: Oicf, W1, Zp8, env = Win32 (exécution 32b) __declspec (uuid()), __declspec (selectany), __declspec (novtable DECLSPEC_UUID(), MIDL_INTERFACE() Vous ne savez pas si cela a quelque chose à voir avec cela. –

+0

Pouvez-vous poster le code que vous utilisez, y compris les parties pertinentes du fichier d'en-tête et le code appelant? –

+0

Bien sûr. J'ai collé le fichier d'en-tête de la bibliothèque ici: http://pastebin.com/m2d66c18c. J'ai collé un exemple (en C) ici: http://pastebin.com/m564b3181. J'utilise l'interface C avec GCC. Le code pertinent commence à la ligne 810 dans le fichier d'en-tête. Je peux appeler les fonctions API Win32 très bien, et selon le fichier d'en-tête, les fonctions de bibliothèque sont de la même convention d'appel que les fonctions WINAPI (STDMETHODCALLTYPE/WINAPI == __stdcall) –

Questions connexes