2010-06-19 13 views
0

J'essaie de créer une DLL qui sera utilisée ultérieurement dans Inno Setup. j'ai réussi à créer une DLL à l'aide Pellès comme un IDE, avec le code suivant:Problème de création/appel d'une DLL

#include <windows.h> 

__declspec(dllexport) int sumT(){ 
    return 2; 
} 

J'appelle la carte de la DLL à une fonction dans Inno Setup, en utilisant le code Delphi suivant:

function Hellow() : Integer ; 
external '[email protected]:yyy.dll stdcall'; 

Cela fonctionne comme prévu, renvoyant 2. Je peux également l'appeler de rundll32.exe - si j'ajoute un MsgBox dans la DLL, il apparaîtra, prouvant que tout fonctionne comme prévu.

Maintenant, le problème commence lorsque je tente de transmettre une valeur à la DLL, comme ça - par exemple:

#include <windows.h> 

__declspec(dllexport) int sumT(int sumTah){ 
    return sumTah; 
} 

Il cesse de fonctionner! Dans Inno Setup, je me donne le message:

"Erreur d'exécution (à -1: 0)"

Et si j'essaie rundll32.exe, je reçois:

erreur dans yyy.dll

d'entrée manquant: SUMT

Je ne vais pas coller le code Delphi ici, parce que j'ai pratiquement tout essayé, même chose avec le code C, j'ai essayé d'utiliser __stdcall à la place, déclarant l'argument comme INT, UINT ... et d'autres choses que j'ai oubliées.

J'ai également recherché le MSDN, mais n'a pas pu trouver quelque chose se rapportant à ce problème particulier.

Alors, quelqu'un peut-il vous aider?

Merci

EDIT: Je suis en C compilerai, donc pas besoin de "extern".

Répondre

2

Le nom exporté ne correspond probablement pas ce que vous pensez qu'il ressemble. Utilisez dumpbin.exe/exports sur la DLL pour voir le nom exporté réel. Utilisez extern "C" pour supprimer le changement de nom.

De plus, vous devez déclarer cette fonction __stdcall, c'est ce que dit votre déclaration Delphi. La valeur par défaut est __cdecl. Cela échouera lorsque vous commencerez à passer des arguments.

+0

Merci pour l'astuce sur l'utilisation de dumpbin.exe Il s'avère que la fonction est exportée en tant que "_sumT @ 4" J'ai trouvé une option dans le compilateur qui dit "Undecorate exporté stdcall functions" (Dans les options de projet -> Compilateur). Ça devrait le faire. BTW __stdcall ne semble pas fonctionner. – Rolf

1

Si vous compilez avec un compilateur C++, le nom de la fonction est tronqué afin qu'il contienne des données sur les arguments. La solution est de faire quelque chose comme:

extern "C" __declspec(dllexport) int myfn();

puis référence comme _myfn. Le extern "C" indique au compilateur de ne pas modifier le nom de la fonction. Cela ne fonctionne pas avec les fonctions modélisées, les classes ou les fonctions surchargées.

+0

Merci. J'ai oublié de mentionner que je compile déjà en C, donc pas besoin de "extern" (AFAIK). Mais la fonction est exportée en tant que _sumT @ 4, donc vous avez raison sur le trait de soulignement. J'ai corrigé cela en définissant une option de compilation ("Undecorate Exported stdcall functions"). – Rolf

+1

Les fonctions stdcall ajoutent le nombre d'octets que la pile prend jusqu'à la fin (le @ 4 dans votre cas, ici); les laisser non décorés peut causer des problèmes de corruption de la pile. Vous voulez probablement le marquer avec la convention d'appel cdecl, qui laissera toujours l'appel sous la forme '_sumT'. – reece

1

__declspec (dllexport) int SUMT (int sumThah) {
retour sumTah;

ressemble à une faute de frappe ou de votre erreur ....

+0

Merci! J'ai réparé ça. – Rolf