DLL的编写与使用(C++)

DLL可以理解为具有一定功能的可以嵌入到可执行程序中的程序片段。

与lib文件一样,DLL在VS中可以有两种编译方式:C编译、C++编译。个人感觉动态加载DLL文件,使用DLL内部函数的时候倒都是一样的。

一、C编译方式。

  A:dll的生成

 1 //File of "sub.h"
 2 #ifndef SUB_H
 3 #define SUB_H
 4 extern "C" int __declspec(dllexport)sub(int x, int y);
 5 #endif
 6 
 7 //File of "sub.cpp"
 8 #include"sub.h"
 9 int sub(int x, int y)
10 {
11     return x-y;
12 }

  B:dll的使用(动态调用)

 1 #include<Windows.h>
 2 typedef int(*lpAddFun)(int, int);
 3 
 4 int main()
 5 {
 6     HINSTANCE hDll;
 7     lpAddFun subFun;
 8 
 9     hDll = LoadLibrary(TEXT("..\\DLL\\DLL_study2.dll"));
10     subFun = (lpAddFun)GetProcAddress(hDll,"sub"/*"?sub@@YAHHH@Z"*/);
11     int x = subFun(3,8);
12     FreeLibrary(hDll);
13 
14     return 0;
15 }

注意问题:如果在生成的时候"sub.h"不加extern "C"那么按照C++的方式编译,编译完成后函数的名字按照C++的方式改写(mangled name)。当动态调用的时候语句 subFun = (lpAddFun)GetProcAddress(hDll,"sub"/*"?sub@@YAHHH@Z"*/); 按照sub就找不到sub函数了。但是按照注释的名字可以。(C++编译的时候将sub函数的名字改成那样了。)也就是说,只要GetProcAddress函数第二个参数(要找的函数名字)与编译生成后的名字一致就行了(不管DLL是什么方式编译成功的)。(很诡异的事情是:当生成了dll后用dependency查看的时候,如果release版本在生成的地方看怎么都是C编译的方式,但是把dll复制到其他地方就该是什么方式就什么方式了。可能是dependency有记忆功能,我前后试过几次他看是一样的文件名就没更改了。)

二、生成DLL的时候使用.def文件。

这样做的时候"sub.h"文件就不用extern “C" 和 __declspec(dllexport)这些东西了。

LIBRARY
EXPORTS
sub @ 1

函数名字就规定为sub了。编译方式貌似是C的(不敢确定dependency  的结果啊!)不过不管是哪种方式函数名字肯定是确定了的啦。

  

posted @ 2013-07-27 10:25  joythink89  阅读(447)  评论(0编辑  收藏  举报