动态(静态)加载DLL注意
来源:互联网 发布:linux 动态库 调试 编辑:程序博客网 时间:2024/06/05 14:15
转自:http://www.cnblogs.com/xiaojinma/archive/2012/12/06/2805577.html
动态加载DLL的方法与注意的问题
动态加载DLL的方法:
1. 生成dll过程:把生成的.DLL文件复制到测试工程DLLTest目录下。这里假设该.DLL文件为add.dll,主要代码是:
// .h中声明
Extern “C” _declspec(dllexport) int add(int x, int y)
// .cpp 中实现
extern "C" int add(int x, int y)
{
return x + y;
}
2.使用1生成的dll:在DLLTest工程中添加DllTest.cpp文件.
首先使用LoadLibrary("add.dll")加载add.dll文件:
HMODULE hmod = LoadLibrary("add.dll");
然后定义一个函数指针的类型:
typedef int (*AddAddr)(int x, int y);
注意,这里的参数与返回类型务必与add.dll文件中函数add的声明一样。
接着:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "add");
如果Add值为空,则获取函数的地址失败!
if(!Add)
{
printf("获取函数地址失败!");
return;
}
最后,可以测试一下:
printf("test add(): 1+2=%d", add(1,2));
运行结果一看,会出现“获取函数地址失败!”。为什么会这样?
打开命令行,用cd命令到add.dll工程目录的debug目录下,然后使用命令:
dumpbin -exports add.dll
则会看到add.dll文件中的add函数的名称为“?add@@YAHHH@Z”,而不是函数名add,这是C++编译器的命名改编机制。 修改原来的代码:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "?add@@YAHHH@Z");
这时运行就成功了。但如果按这样去动态加载DLL,那每次获取函数地址都要使用dumpbin命令去获取,则会很麻烦。
那怎样可以直接使用add而不是 ?add@@YAHHH@Z这个长长的字符串呢,修改add.dll的add函数,在函数前加上extern "C",再编译add.dll文件所在的工程,复制新生成的add.dll覆盖DLLTest工程目录下的add.dll,原来的代码获取函数地址时使用add,结果运行就成功了。
而再使用dumpbin -exports add.dll命令,显示add.dll的中的add函数的名称变成了add.
静态加载
隐式链接会把DLL中所有标志为_declspec(dllexport)的函数都加载,如果有多个DLL加载时,可能会影响到程序执行的效率。而用动态加载DLL的方式则可以根据需要去加载用到的函数。
// .h中
#ifdef COUNTER_EXPORTS
#define COUNTER_API _declspec(dllexport)
#else
#define COUNTER_API _declspec(dllimport)
#endif
// 声明要导出的函数
int COUNTER_API WINAPI _IncCounter();
----------------------------------------------------------------------------------------------------------
// .cpp中
int WINAPI _IncCounter()
{
dwCounter ++;
_CheckCounter(dwCounter);
return dwCounter;
}
----------------------------------------------------------------------------------------------------------
// .def
EXPORTS
_IncCounter
----------------------------------------------------------------------------------------------------------
#include "Counter.h"
#pragma comment(lib, "Counter.lib")
----------------------------------------------------------------------------------------------------------
动态链接库中共享
// 共享数据段
#pragma data_seg("mahongmou")
HWND g_hWndCaller = NULL; // 保存主窗口句柄
HHOOK g_hHook = NULL; // 保存钩子句柄
#pragma data_seg()
-------------------------------------
SECTIONS
mahongmou Read Write Shared
- 动态(静态)加载DLL注意
- 静态加载dll和动态加载dll
- 静态加载dll和动态加载dll
- 静态加载dll和动态加载dll
- DLL的静态加载和动态加载
- 动态库DLL加载方式-静态加载和动态加载
- 动态库DLL加载方式-静态加载和动态加载
- 动态库DLL加载方式-静态加载和动态加载
- 动态加载DLL和静态加载DLL的步骤
- 动态加载DLL和静态加载DLL的步骤
- vc静态加载dll和动态加载dll
- vc静态加载dll和动态加载dll
- 静态加载dll,动态加载dll及常见问题处理
- MFC静态加载dll和动态加载dll示例
- DLL加载方式-动态vs静态
- 静态与动态加载Dll [示例代码]
- 静态链接与动态加载DLL
- 动态链接库dll的 静态加载 与 动态加载
- SSH用户权限管理(三)
- HDU 2795 Billboard【线段树好题,单点更新】
- 动态链接库dll的 静态加载 与 动态加载
- 【Unity】获得当前脚本的物体的transform和gameobject
- C风格字符串
- 动态(静态)加载DLL注意
- Java运行时的数据区域
- node.js学习总结
- table的作用以及优缺点
- Android热修复动手实现
- android 仿qq的侧滑删除功能
- 篇六之IO多路复用——select、poll、epoll
- 动态加载vs静态加载
- BZOJ3622: 已经没有什么好害怕的了