Sunshine Alike

半完美主义

  C++博客 :: 首页 :: 联系 :: 聚合  :: 管理
  35 Posts :: 1 Stories :: 56 Comments :: 0 Trackbacks

常用链接

留言簿(15)

积分与排名

  • 积分 - 49576
  • 排名 - 451

最新随笔

最新评论

一直对动态链接库这个东西很陌生,今天刚好调试别人写的一个DLL项目,顺便就来研究一下下。
动态链接库的原理,好处那些就先不说了,直接来看怎么使用。
首先写一个动态链接库,其中 __declspec(dllexport)是用于MS编译器的一个关键字,用来将DLL中的内容导出而不需要.def文件了。
下面的cpp里就函数的定义了,DllMain函数跟普通的win32 console的main函数很像。
使用cl /c DLLImplement.cpp
link /dll DLLImplement.obj
就可以得到一个DLLImplement.dll顺便也会导出一个
DLLImplement.lib这个跟静态链接库很像的东西,实际上它的作用只是导出那些方法和变量的名字。

1 extern "C"
2 {
3     __declspec(dllexport) void Set(int i);
4     __declspec(dllexport) int Get();
5     __declspec(dllexport) void SayHello();
6 
7     int value;
8 }
 1 #include <iostream>
 2 #include <objbase.h>
 3 #include "DLLHeader.h"
 4 
 5 
 6 void Set(int i)
 7 {
 8     value = i;
 9 }
10 int Get()
11 {
12     return value;
13 }
14 void SayHello()
15 {
16     std::cout<<"Hello, I'm DLL, value is "<<value<<std::endl;
17 }
18 
19 
20 BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, void* lpReserved)
21 {
22     HANDLE g_hModule;
23 
24     switch(dwReason)
25     {
26     case DLL_PROCESS_ATTACH:
27        std::cout<<"DLL is attached!"<<std::endl;
28        g_hModule = (HINSTANCE)hModule;
29        break;
30 
31     case DLL_PROCESS_DETACH:
32        std::cout<<"DLL is detached!"<<std::endl;
33        g_hModule=NULL;
34        break;
35     }
36 
37     return TRUE;
38 }
39 


使用DLL的方法,有3种:使用def文件/使用LoadLibrary和GetProcAddress方法/使用导出的lib配合头文件。
第一种太麻烦这里不介绍,只说明一下后两种的使用方法。
 1 #include <iostream>
 2 #include <windows.h>
 3 
 4 typedef void (*SET)(int);
 5 typedef int (*GET)(void);
 6 typedef void (*SAYHELLO)(void);
 7 
 8 int main(int argc, char **argv)
 9 {
10     SET pSet = 0;
11     GET pGet = 0;
12     SAYHELLO pSayHello = 0;
13 
14     HINSTANCE hinst=::LoadLibrary("DLLImplement.dll");
15     if (0 == hinst)
16     {
17         std::cout<<"load dll failed!"<<std::endl;
18         return -1;
19     }
20 
21     pSet = (SET)GetProcAddress(hinst, "Set");
22     pGet = (GET)GetProcAddress(hinst, "Get");
23     pSayHello = (SAYHELLO)GetProcAddress(hinst, "SayHello");
24 
25     if (0 == pSet || 0 == pGet || 0 == pSayHello)
26     {
27         std::cout<<"get function failed!"<<std::endl;
28         return -1;
29     }
30 
31     //ready to call the function
32     (*pSet)(10);
33     int i = (*pGet)();
34     std::cout<<"Get value from dll, value is "<<i<<std::endl;
35     (*pSayHello)();
36 
37     return 0;
38 }
这种调用方法属于显示调用,使用的时候需要知道DLL文件的路径,还有DLL里面的方法的名字,还是有点不太方便。更多的时候,都是使用最后一种隐式调用的方法,即配合头文件和导出的lib,需要在进行链接的时候加入DLLImplement.lib即可,方法如下:
 1 #include <iostream>
 2 #include "DLLHeader.h"
 3 
 4 using namespace std;
 5 
 6 
 7 int main (int argc, char **argv)
 8 {
 9     Set(100);
10     cout<<"Set value in DLL"<<endl;
11     int i = Get();
12     cout<<"Get value in DLL, value is "<<i<<endl;
13 
14     SayHello();
15     return 0;
16 }
到这里对DLL有了一个大概的感性认识,具体的理论性的知识,等有机会慢慢再写出来。

抱怨一句,最近有点懒了,想要写的日志都没写。
找实习也麻烦,写代码肩膀脖子酸痛。
IT民工的命咋就这么苦哩。
posted on 2010-07-08 00:24 Sunshine Alike 阅读(517) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理