我在一个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);”造成了这个问题。 有人可以帮助我吗?
答案 0 :(得分:1)
我认为你混淆了两件事:
__declspec(dllexport)
MSVC关键字从DLL导出函数(告诉链接器执行此操作),__declspec(dllimport)
从DLL导入函数。这是在加载时完成的,链接器将创建加载DLL并解析符号的所有必要代码。实际上,它为exe添加了一些代码以让操作系统加载DLL。您可以使用__declspec(dllimport)
声明的函数,就像任何正常的内部函数一样。
如果要使用此方法,则需要DLL的lib文件,因为它包含链接器解析符号名称的信息。它实际上并不包含代码,只有链接器的DLL上的这些信息。此外,您必须告诉链接器您要使用的函数位于DLL,在函数声明之前使用magic __declspec(dllimport)。这就是为什么你要用你的DLL提供一个.lib和一个头文件(包含这些声明),如果你想这样做的话。您应该在更改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并且不运行该过程。)