DLL是一组源代码模块,每个模块提供程序一些功能。
DLL 不能拥有资源 在它的模块中申请的资源对象归线程所有 如果DLL 被freelibrary(),对象不会被卸载。
但线程卸载,资源就会被释放。
DLL的建立
.h文件 包含导出的函数
静态库编译器会编译器包含符号表和代码
动态库编译器会生成个小体积的LIB文件 它不包含代码 只有符号表 代码在DLL中
__declspec(dllimport)
__declspec(dllexport)
隐式调用
通过包含LIB 文件或静态LIB文件,
在程序连接的时候会产生导入表的一些信息。当程序运行的时候会先载入导入表中的需要的DLL
这个是深度优先的算法。
初始化完毕后,有了DLL得确定地址 就可以调用了
显示调用
当程序链接的时候 并没有显示调用的DLL信息,所以没有它里面的函数信息
必须动态获得函数地址 并通过此地址进行调用
HMODULE LoadLibrary( LPCTSTR lpFileName // file name of module );
sucess返回的是这个DLL的加载地址
faild 返回的是NULL
如果想获得这个DLL中的函数地址
通过
FARPROC GetProcAddress( HMODULE hModule, // handle to DLL module LPCSTR lpProcName // function name );
参数1 模块名
参数2 方法名
参数2 可以通过序号查找 但是字符串 可以利用一个宏进行转换 MAKEINTRESOURCE
返回函数地址 可以进行转换
说道这里突然想到一些别的东西 神马调用方式啊 __cdecl(c /c++ 调用 C++可以改变 但是对于变参的函数 必须用_cdecl) _stdll(c++默认调用方式 ) 都是从右到左 压入参数 但平衡的堆栈的事 一个要靠 调用者 一个靠自己 _thiscall 编译器决定 VC ecx==this D是EAX调用
window 是_stdll 调用方式
链接器对这个有需要
但是当得到一个函数地址时 你可以随便转换它 只要参数对就行 多语言联合编程 只要参数对 能接受返回信息就行 不用管内部实现