动态链接库的概念(个人理解):
1.它是给其他程序调用的函数库
2.它被使用时,系统中仅有一份代码在内存中,即使有多个程序在使用它.
3.其他程序使用动态链接库时,"行为人"属于调用方,也就是说报错追责和动态库没关系,不影响其他程序正常使用动态链接库的东西;
动态库怎么写(有哪些内容构成):
- 动态库也有入口(这是给加载器用的回调函数)
//直接粘贴一个
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call, LPVOID lpReserved){
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
//(动态库文件有权知道注入进程的所有线程创建,结束)
//DLL_THREAD_ATTACH:该通知告诉所有的DLL执行线程的初始化。
//当进程创建一个新线程时,系统会查看进程地址空间中所有的DLL文件映射,
//之后用DLL_THREAD_ATTACH来调用DLL中的DLLMain函数。
//要注意:系统不会为进程的主线程使用值DLL_THREAD_ATTACH来调用DLL中的DLLMain函数
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
- 项目内容分 导出/内部 内容
//_declspec(dllexport) //表明要输出的内容
_declspec(dllexport) int MyAdd(int a, int b);//输出函数MyAdd
//另外有用c语言的方式 导出的形式
extern "c"{
_declspec(dllexport) int MyAdd(int a, int b);//输出函数MyAdd
}
动态库怎么写(有哪些内容构成):
根据连接时机的不同,有两种使用方式
- 装载期间连接:
1.在工程里设置链接
2.代码指定链接的函数库
#include "xxx.h" //函数的定义的头文件要有
#pragma commend(lib,"xxxx")//xxxx就是要连接的函数库如:xxx.lib
说明:两方法本质相同
- 运行期间链接:
在运行期间链接常用到的函数有
int (pf*)(int,int); //提前定义一下要使用导出函数
HMODULE hModule = ::LoadLibrary("xxx.dll");
xxx pf = ::GetProcAddress(HModule,"MyAdd");
if (pf!=NULL){
pf(1,3);
}
说明:c++和c的导出函数处理不同,大体可以这么理解
c++对函数名做一些特殊处理,而c没有,所以对于extern "c"导出的函数,可以直接使用上边例子,而c++则需要额外写一个.def的文件,例如:
LIBRARY "DllTest"
EXPORTS
MyAdd
MySub
g_int DATA
有了def文件之后,c++导出的dll才能正常使用!