Chinaunix首页 | 论坛 | 博客
  • 博客访问: 423476
  • 博文数量: 45
  • 博客积分: 4075
  • 博客等级: 上校
  • 技术积分: 666
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-24 18:09
个人简介

百度网页搜索部高级工程师 我的微博:http://weibo.com/pengwh85

文章分类

全部博文(45)

文章存档

2012年(3)

2011年(1)

2010年(19)

2009年(10)

2008年(12)

我的朋友

分类: C/C++

2008-07-30 21:50:58

    加载DLL的方法主要有两种:一种是隐式链接,另外一种是动态加载。
    隐式链接会把DLL中所有标志为_declspec(dllexport)的函数都加载,如果有多个DLL加载时,可能会影响到程序执行的效率。而用动态加载DLL的方式则可以根据需要去加载用到的函数。
    动态加载DLL的方法:
    1.把生成的.DLL文件复制到测试工程DLLTest目录下。这里假设该.DLL文件为add.dll,主要代码是:
_declspec(dllexport) int add(int x, int y)
{
    return x + y;
}
 
    2.在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,这是C++编译器的命名改编机制。 修改原来的代码:
AddAddr Add = (AddAddr)GetProcAddress(hmod, "");
这时运行就成功了。但如果按这样去动态加载DLL,那每次获取函数地址都要使用dumpbin命令去获取,则会很麻烦。
 
那怎样可以直接使用add而不是 这个长长的字符串呢,修改add.dll的add函数,在函数前加上extern "C",再编译add.dll文件所在的工程,复制新生成的add.dll覆盖DLLTest工程目录下的add.dll,原来的代码获取函数地址时使用add,结果运行就成功了。
 
而再使用dumpbin -exports add.dll命令,显示add.dll的中的add函数的名称变成了add.
阅读(9982) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-10-23 11:38:55

只要是需要导出的函数,那么就一定要使用extern "C",而不是要去dumpbin。编译器可能会改变函数的名称,而如何改变不在标准里边。