[转] 显式加载DLL并使用 DLL 中的类

C&C++ 专栏收录该内容
3 篇文章 0 订阅

    首先需要强调,当使用某个类时一般目的有二:实例化成对象或者继承它产生新类。
对于前者,我们可以构造一个抽象类(java里的接口)来连接调用方和DLL。
 
抽象类:
// Interface.h  公共文件/
#pragma  once
 
class  Interface
{
public :
     virtual void ShowMsg() = 0; //  将调用方需要调用的成员函数声明成纯虚函数
     virtual ~Interface(){};//  抽象类的虚析构函数
};
 
 
// Interface.cpp  被调用方文件
//  注意下面的代码并不是实现 Interface 类,而是因为联系紧密才写在这。
#include  "stdafx.h"
#include  "Test.h"
#include  "Interface.h"
 
//  通过导出函数形式向调用方提供指向派生类对象的基类指针
extern  "C" __declspec(dllexport) Interface* Export(void)
{
     return (Interface*)new Test();
}
 
将真正要调用的类声明成抽象类 Interface 的派生类:
// Test.h  被调用方文件//
//  类的声明
#pragma  once
#include  "Interface.h"
class  Test:public Interface
{
public :
     Test()
     virtual ~Test();
     virtual void ShowMsg(void);
private :
     CString s;
};
 
// Test.cpp  被调用方文件
//  类的实现
#include "stdafx.h"
#include "Test.h"
 
Test::Test()
{
     s = "hello form dll";
}
 
Test::~Test()
{
     AfxMessageBox(_T("destructor"));
}
 
void  Test::ShowMsg()
{
     AfxMessageBox(s);
}
 
在调用方调用DLL时动态加载:
//  调用方文件 /
#include  "stdafx.h"
#include  "Interface.h" //  包含抽象类从而使用接口
 
//  在调用处添加如下代码
     HINSTANCE hDll;
     hDll = LoadLibrary(_T("module1.dll"));//  加载DLL库文件,DLL名称和路径用自己的
     if(hDll == NULL)
     {
         TRACE("/n/nload dll fail/n/n");
         return;
     }
     typedef Interface*(*pExport)(void); //  定义指向导出函数的指针类型
     pExport Get;
     Get = (pExport)GetProcAddress(hDll,"Export");//  将指针指向函数首地址
     if(Get == NULL)
     {
         TRACE("/n/nload address fail/n/n");
         return;
     }
    
     Interface *t = Get();//  调用导出函数获得抽象类指针
     t->ShowMsg();//  通过该指针调用类成员函数
     delete t; //  释放DLL中生成的对象
     FreeLibrary(hDll); // 释放库句柄
 
 
写到这第一个目的达到了。其实将需要调用的类的指针直接导出更简单,但是使用抽象类接口
却更加优雅,思路也比较清晰(在这方面java比较舒服)。
 
     至于继承DLL中的类,最好的方法是使用扩展DLL。其实我们应该尽量避免继承DLL中的类。
动态链接库顾名思义是可以随时更新动态链接到程序的模块库,目的是方便程序的模块化和动
态更新。而继承的本意是为了实现多态,多态的基础就是所有同一基类的派生类可以通过相同
基类指针来访问,基类是所有派生类的抽象,是基石,是很少甚至不可改变的。因此把基类放在
动态链接库,然后从外面去继承他是不明智也是很奇怪的。
    个人理解有限,高手不要见笑。

转自 http://blog.csdn.net/maxttyl/article/details/1537023
  • 0
    点赞
  • 0
    评论
  • 0
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值