在函数声明前加__declspec(...)
-声明时:
extern "C"{
#ifdef _DLL_SAMPLE
#define DLL_SAMPLE_API __declspec(dllexport)
#else
#define DLL_SAMPLE_API __declspec(dllimport)
#endif
int a = 255;
DLL_SAMPLE_API void TestDll(int);
#undef DLL_SAMPLE_API
}
-调用时:(调用方法可以参照前面的DLL链接)
typedef void (*Test)(int);
HINSTANCE hInstLib = LoadLibrary(_T("..\\debug\\DLLTeat.dll"));
if (hInstLib == NULL)
{
return -1;
}
Test _Test;
_Test = (Test)GetProcAddress(hInstLib,"TestDll");
if (_Test==NULL)
{
return -1;
}
_Test(a);
......
采用模块定义(.def)文件声明
-在创建的DLL头文件中声明函数:
#ifndef _DLLTEST_H_
#define _DLLTEST_H_
extern "C"{
int __stdcall Add(int a,int b);
int Sub(int a,int b);
}
#endif
-创建一个.def文件(VS2008创建时会自动生成第一行的内容)
;说明.def文件对应的DLL
LIBRARY "DLLTestDef"
EXPORTS
Add @1
Sub @2
- .def文件的内容解析
--LIBRARY "DLLTestDef" ==》 说明.def文件对应的DLL,可以更改名字,不影响使用结果。
--EXPORTS ==》这一句之后列出要导出的函数的名称
--Add @1 ==》函数名 @n,其中n表示要导出的函数的序号
--.def文件中的注释由每个注释行开始处的 ; 指定,且注释不能和语句共用一行
-调用时:
//头文件Windows.h 和iostream
typedef int (__stdcall *Func1)(int,int);
typedef int (*Func2)(int,int);
HINSTANCE hInstLib = LoadLibrary(_T("..\\debug\\DLLTestDef.dll"));
if(hInstLib == NULL)
{
cout<<"Find DLL Error!"<<endl;
return 0;
}
Func1 func1;
Func2 func2;
func1 = (Func1)GetProcAddress(hInstLib,MAKEINTRESOURCEA(1));
func2 = (Func2)GetProcAddress(hInstLib,MAKEINTRESOURCEA(2));
if (func1 == NULL)
{
cout<<"Find Func1 Error!"<<endl;
}
if (func2 == NULL)
{
cout<<"Find Func2 Error!"<<endl;
}
cout<<func1(3,1)<<endl;
cout<<func2(3,1)<<endl;
使用__declspec 和 .def 的区别(在VS2008里)
在DLL中使用extern "C"
- 使用__declspec时,DLL中定义的函数如果加了 __stdcall ,在调用时会找不到函数;普通函数找到 _函数名
- 使用 .def 时,DLL中定义的函数如果加了 __stdcall ,在调用时找到的函数结果为 _函数名@n;普通函数找到 _函数名
- n是与参数有关。比如参数为两个int时,n为8;一个int时,n为4。
- 如果.def文件中的函数不完整,那么在调用相应的GetProcAddress函数时,找不到函数的地址。
在DLL中不使用extern "C"
- 用.def的方式,调用函数结果为函数名 (参数列表)
- 用__declspec的方式,调用GetProcAddress会找不到对应的函数
网友评论