2010-09-16 64 views
0

我有以下在一个DLL中定义函数:问题DLL调用以书面形式调用进程

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

我需要编写一个程序来调用上面的函数。 我正在做第一次,我没有太多的想法。 我已经写以下代码

#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; 
} 

的 “(ADD)(A,AA,B,C);”正在造成这个问题。 有人可以帮我吗?

回答

1

我想你搅拌两次的事情了:从DLL(通知链接这样做),并从一个DLL的__declspec(dllimport)进口功能
__declspec(dllexport) MSVC关键字出口功能。这是在加载时完成的,链接器将创建所有必要的代码来加载DLL并解析符号。实际上,它会向exe文件添加一些代码,以便让操作系统加载DLL。就像任何正常的内部函数一样,您可以使用__declspec(dllimport)声明的函数。

如果您想使用这种方法,您需要DLL的lib文件,因为它包含链接器解析符号名称的信息。它实际上并不包含代码,只有这些链接器的DLL信息。另外,你必须告诉链接器你要使用的函数位于DLL中,在函数声明前使用魔术__declspec(dllimport)。这就是为什么你提供一个.lib和一个头文件(包含这些声明)与你的DLL,如果你想这样做。您应该在更改DLL时重建使用该DLL的项目,因为.lib文件可能已更改。 您可以使用您的DLL项目相同的头文件和项目,从这个DLL导入:

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

MYDLL_API void printMe(int);

的MyDLL_API得到解决要么__declspec(dllexport)的(在DLL项目,您在定义MYDLL_EXPORTS项目设置)或__declspec(dllimport)(在所有使用dll的项目中)。这样,您只需要一个DLL的头文件。

调用DLL函数的另一种方法是使用LoadLibrary和GetProcAdress。这两个用于在运行时加载DLL。在加载时和运行时加载DLL的主要区别在于,您可以在运行时加载DLL,而操作系统将在加载时加载DLL时执行该任务(例如,如果在加载时显示消息框DLL无法找到并且不运行该进程)。