2010-09-16 5 views
0

je suit la fonction définie dans l'une dll:problème dans l'appel dll par écrit le processus d'appel

__declspec(dllexport) int __stdcall 
mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile) 

Je dois écrire un processus pour appeler la fonction ci-dessus. Je le fais la première fois, je n'ai pas trop d'idée. J'ai écrit le code suivant

#include <windows.h> 
#include <windows.h> 
#include <stdio.h> 
#include <io.h> 
#include <stdlib.h> 
#include <limits.h> 
extern __declspec(dllexport) int __stdcall mjscall(char *cmd, DWORD wtime, char *stdoutfile, char *stderrfile); 
typedef INT (*MJSCALL) (char *,DWORD, char *, char *); 
int main() 
{ 

    char *a,*b,*c; 
    a=NULL; 
    b=NULL; 
    c=NULL; 
    DWORD aa =1; 
    int i; 
    HMODULE hLib; 
    MJSCALL ADD; 
    hLib=LoadLibrary("f3cucall.dll"); 
    if(hLib==NULL) 
    { 
     return 1; 
    } 
    ADD=(MJSCALL)GetProcAddress(hLib,"mjscall"); 
    if (ADD==NULL) 
    { 
     return 1; 
    } 

    (ADD)(a,aa,b,c); 
    return 0; 
} 

Le "(ADD) (a, aa, b, c);" est à l'origine du problème. Quelqu'un peut-il m'aider?

Répondre

1

Je pense que vous avez mélangé deux choses:
les exportations __declspec(dllexport) mot-clé MSVC fonctions à partir d'une DLL (dit l'éditeur de liens pour le faire), et les fonctions __declspec(dllimport) des importations d'une DLL. Ceci est fait au moment du chargement, l'éditeur de liens créera tout le code nécessaire pour charger la DLL et résoudre le symbole. En fait, il ajoute du code à l'exe pour laisser le système d'exploitation charger la DLL. Vous pouvez utiliser les fonctions déclarées avec __declspec(dllimport) comme n'importe quelle fonction interne normale.

Si vous souhaitez utiliser cette approche, vous avez besoin du fichier lib de la DLL, car il contient des informations sur l'éditeur de liens pour résoudre le nom symbolique. Il ne contient pas réellement de code, seulement ces informations sur la DLL pour l'éditeur de liens. En outre, vous devez indiquer à l'éditeur de liens que la fonction que vous souhaitez utiliser se trouve dans une DLL, en utilisant le script magique __declspec (dllimport) avant la déclaration de la fonction. C'est pourquoi vous fournissez un .lib et un fichier d'en-tête (contenant ces déclarations) avec votre DLL si vous voulez le faire de cette façon. Vous devez reconstruire le projet qui utilise la DLL lorsque vous modifiez la DLL, car le fichier .lib peut avoir changé. Vous pouvez utiliser le même fichier d'en-tête dans votre projet DLL et les projets qui importent de cette DLL:

#ifdef MYDLL_EXPORTS 
#define MYDLL_API __declspec(dllexport) 
#else 
#define MYDLL_API __declspec(dllimport) 
#endif 

MYDLL_API void printMe(int);

Le MyDLL_API se résoudre soit __declspec (dllexport) (dans le projet de DLL, où vous définissez les MYDLL_EXPORTS dans les paramètres du projet) ou __declspec (dllimport) (dans tous les projets qui utilisent la DLL). De cette façon, vous n'avez besoin que d'un fichier d'en-tête pour la DLL.

Une autre méthode d'appel des fonctions DLL consiste à utiliser LoadLibrary et GetProcAdress. Ces deux sont utilisés pour charger une DLL lors de l'exécution. La principale différence entre le chargement d'une DLL au moment du chargement et au moment de l'exécution est que vous avez un certain contrôle sur le chargement de la DLL au moment de l'exécution, alors que le système exécutera le chargement au moment du chargement. DLL ne peut pas être trouvé et ne pas exécuter le processus).