您的位置:首页 > 其它

DLL运行期间动态加载

2012-11-05 10:11 239 查看
昨天晚上,DLL导入导出的问题折腾了我好一阵子,网上搜索了,看了很多网页却收益甚小,或许人人都是按照自己的想法或者自己的所需发表在网上吧.下面把自己的问题记录下来,并把解决的思路、方法也写下来,以备后用。

//dlltest.h文件

extern "C"
{
__declspec(dllexport) int _stdcall add(int a, int  b);
}

//dlltest.cpp文件

#include "dlltest.h"

__declspec(dllexport) int _stdcall  add(int a, int  b)
{
return a+b;
}

以上是DLL的生成工程中的文件,运行会生成dlltest.dll文件(当然要工程属性设置的配合)。

调用DLL的工程的dlluse.cpp文件

int _tmain(int argc, _TCHAR* argv[])
{
typedef int (/*_stdcall*/  *padd)(int a,int b); //定义函数指针类型
HINSTANCE hInstance=LoadLibrary("dlltest.dll");
padd add = (padd)GetProcAddress(hInstance,"add");
if(!add)
{
cout<<"动态连接库库函数未找到"<<endl;
}
getchar();
return 0;
}

运行调用DLL的工程生成的exe文件,会提示"动态连接库库函数未找到"。\Common7\Tools\Bin\depends.exe用vs2005自带的这个工具看dlltest.dll,会发现根本不存在"add”函数,这个问题主要是_stdcall 使用不明白造成的。dlluse.cpp中把"add"改为"_add@8"就可以了,或者把dlltest.h、dlltest.cpp中的_stdcall去掉。

下面是原因及总结:

1、函数调用约定方式_stdcall、__cdecl,_cdecl是C和C++程序的缺省调用方式。“对于C,__stdcall命名约定使用以下划线(_)开头的函数名,后跟"at”符(@)和函数参数大小(以字节为单位)”.

2、被extern "C"修饰的变量和函数是按照C语言方式编译和连接的,C++支持函数重载,而过程式语言C则不支持,函数被C++编译后在符号库中的名字与C语言的不同。

3、depends.exe这个工具还是挺好的,depends.exe 可以用来查看函数的入口点可以看到dll中导出函数的名称。vs2005中的depends.exe要到\Common7\Tools\Bin\depends.exe找, VS2008 中depends.exeWindows SDK组评估为质量不合格下岗了。

本文出自 “每日C” 博客,请务必保留此出处http://dailyc.blog.51cto.com/6187762/1050203
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: