c++显式加载dll并使用DLL的类

转载自:


http://blog.163.com/tianjunqiang666@126/blog/static/8725911920121064573594/

首先需要强调,当使用某个类时一般目的有二:实例化成对象或者继承它产生新类。
对于前者,我们可以构造一个抽象类(java里的接口)来连接调用方和DLL。
// Interface.h  公共文件/ 公共接口

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 下列 ifdef 块是创建使从 DLL 导出更简单的  
  2. // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 INTERFACE_EXPORTS  
  3. // 符号编译的。在使用此 DLL 的  
  4. // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将  
  5. // INTERFACE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的  
  6. // 符号视为是被导出的。  
  7. #ifdef INTERFACE_EXPORTS  
  8. #define INTERFACE_API __declspec(dllexport)  
  9. #else  
  10. #define INTERFACE_API __declspec(dllimport)  
  11. #endif  
  12.   
  13. #pragma once  
  14.   
  15. class Interface  
  16. {  
  17. public:  
  18.     virtual void ShowMsg() = 0; // 将调用方需要调用的成员函数声明成纯虚函数  
  19.     virtual ~Interface(){};// 抽象类的虚析构函数  
  20. };  
  21. extern "C" INTERFACE_API InterfaceExport(void);  
// Interface.cpp  被调用方文件


//  注意下面的代码并不是实现 Interface 类,而是因为联系紧密才写在这。

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // Interface.cpp : 定义 DLL 应用程序的导出函数。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "Interface.h"  
  6. #include <iostream>  
  7. #include "test.h"  
  8.   
  9.   
  10. // 通过导出函数形式向调用方提供指向派生类对象的基类指针  
  11. Interface* Export(void)  
  12. {  
  13.     return (Interface*)new Test();  
  14. }  

将真正要调用的类声明成抽象类 Interface 的派生类:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #pragma once  
  2. #include "Interface.h"  
  3. #include <string>  
  4. class Test :public Interface  
  5. {  
  6. public:  
  7.     Test();  
  8.     virtual ~Test();  
  9.     virtual void ShowMsg(void);  
  10. private:  
  11.     std::string s;  
  12. };  

// Test.cpp  被调用方文件


//  类的实现
[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include "stdafx.h"  
  2. #include "test.h"  
  3. #include <iostream>  
  4.   
  5. Test::Test()  
  6. {  
  7.     s = "hello form dll";  
  8. }  
  9.   
  10. Test::~Test()  
  11. {  
  12.     std::cout << "destroy";  
  13. }  
  14.   
  15. void Test::ShowMsg()  
  16. {  
  17.     std::cout << s << std::endl;  
  18. }  


调用方调用DLL时动态加载:

[cpp]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. #include <Windows.h>  
  2. #include <iostream>  
  3. #include "Interface.h" // 包含抽象类从而使用接口  
  4.   
  5. // 在调用处添加如下代码  
  6. using pExport = Interface* (*)(void); // 定义指向导出函数的指针类型  
  7.   
  8. int main()  
  9. {  
  10.     HINSTANCE hDll = LoadLibrary("Interface.dll");// 加载DLL库文件,DLL名称和路径用自己的  
  11.     if (hDll == NULL)  
  12.     {  
  13.         std::cout << "load dll fail \n";  
  14.         return -1;  
  15.     }  
  16.     pExport Get = (pExport)GetProcAddress(hDll"Export");// 将指针指向函数首地址  
  17.     if (Get == NULL)  
  18.     {  
  19.         std::cout << "load address fail \n";  
  20.         return -1;  
  21.     }  
  22.   
  23.     Interface *t = Get();// 调用导出函数获得抽象类指针  
  24.     t->ShowMsg();// 通过该指针调用类成员函数  
  25.     delete t; // 释放DLL中生成的对象  
  26.     FreeLibrary(hDll); //释放库句柄  
  27.     system("pause");  
  28.     return 0;  
  29. }  


此时需要注意两点:

1.我们需要把Interface.h放在UseDLL工程目录下

2.如果编译时出现:无法将参数 1 从“const char [14]”转换为“LPCWSTR”的错误,则我们需要

点击项目属性,常规-》字符集-》改为“未设置”即可

实际上整个项目的方法是Interface完成了接口的设置,而具体的实现在test中进行,真正使用了类的抽象性和多态性,封闭性。

项目下载路径:http://7xs15g.com1.z0.glb.clouddn.com/Interface.zip



http://blog.csdn.net/xiamentingtao/article/details/51052925

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值