DLL运行期间动态加载

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

   
   
   
   
  1. //dlltest.h文件 
  2.  
  3. extern "C" 
  4.   __declspec(dllexport) int _stdcall add(int a, int  b); 
  5.  
  6. //dlltest.cpp文件 
  7.  
  8. #include "dlltest.h" 
  9.  
  10.  __declspec(dllexport) int _stdcall  add(int a, int  b) 
  11.  { 
  12.    return a+b; 
  13.  } 

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

   
   
   
   
  1. 调用DLL的工程的dlluse.cpp文件 
  2.  
  3. int _tmain(int argc, _TCHAR* argv[]) 
  4.   typedef int (/*_stdcall*/  *padd)(int a,int b); //定义函数指针类型 
  5.   HINSTANCE hInstance=LoadLibrary("dlltest.dll"); 
  6.   padd add = (padd)GetProcAddress(hInstance,"add"); 
  7.   if(!add) 
  8.   { 
  9.     cout<<"动态连接库库函数未找到"<<endl
  10.   } 
  11.   getchar(); 
  12.   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++,dll,vs)