今天用了一下动态库,在此做一些总结。
一、动态库的创建
新建一个动态库 (WCE Dynamic-Link Library),
工程名输入dlltest,
选择A simple Windows CE DLL project创建一个简单的Windows CE的动态库,
此时会自动生成一个cpp文件,里面自动生成了动态库入口函数
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
,此时编译生成一个.dll文件,此文件是没有输出接口的,只有一个输入接口,也没有生成.lib文件,用PE分析结果如下:
以下是导入函数表:
COREDLL.dll
COREDLL.36
--------------------------------------------------------------------------------
以下是导出函数表:
共导出函数:0,有名函数:0
下面声明定义一个函数
int testFunc( void)
{}
,此时再编译发现生成的dll还是没有输出接口,也没有生成.lib文件,用PE分析结果同上面一样,testFunc并没有编译进dll中,就很奇怪。
原来dll中的输出接口需要一段声明,修改成如下代码则可,
__declspec(dllexport) int testFunc(void)
{}
,此时再编译发现生成的dll中有了一个输出接口,用PE分析结果如下:
以下是导入函数表:
COREDLL.dll
COREDLL.36
--------------------------------------------------------------------------------
以下是导出函数表:
共导出函数:1,有名函数:1
?testFunc@@YAHXZ 1 0x1005
,用__declspec(dllexport)来声明是导出函数。
这个是c++的动态库,在c语言中是没法使用的,如果想要生成c的动态库则需要在函数声明时加上一个转换,
extern "C" __declspec(dllexport) int testFunc( void)
{}
加上 extern “C” 就把函数定义成了c语言的格式,此时再用PE工具查看dll接口如下:
以下是导入函数表:
COREDLL.dll
COREDLL.36
--------------------------------------------------------------------------------
以下是导出函数表:
共导出函数:1,有名函数:1
testFunc 1 0x1005
,此时的导出函数就没有了乱七八糟的字符(?testFunc@@YAHXZ 1 0x1005),完全是c语言的动态库标准,c/c++程序中都可以调用。
二、动态库的调用
动态库的调用有两种方式,一种是静态链接,一种是动态链接。
静态链接就是使用动态库生成的时候生成的.lib文件,就像使用静态库一样使用,dll文件必须放在系统目录下或者调用他的模块同目录下。
#pragma comment(lib, "xxx.lib");
动态链接方法如下:
首先要顶一个一个函数指针
typedef int(__cdecl *L_testFunc)(void);
此声明的意思是,声请一个名为L_testFunc指向一个参数为void返回值为int形的函数的指针。
然后需要加载动态库
HINSTANCE hDll = LoadLibrary(_T("dlltest.dll"));
L_testFunc lpFunc = (L_testFunc)GetProcAddress(hDll, _T("testFunc"));
然后就可以调用函数了
lpFunc();
最后需要将动态库关闭
FreeLibrary(hDll);
ok,完毕!