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


    首先需要强调,当使用某个类时一般目的有二:实例化成对象或者继承它产生新类。
对于前者,我们可以构造一个抽象类(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
    评论
### 回答1: Windows可以通过LoadLibrary() API函数DLL,然后使用GetProcAddress() API函数获取DLL的函数指针。以下是示例代码:HMODULE hMod = LoadLibrary("Path/To/Dll.dll");if (hMod == NULL) { // Error loading the library return; }// Get the address of the exported function FARPROC procAddr = GetProcAddress(hMod,"ExportedFunction");if(procAddr == NULL) { // Error getting the proc address return; }// Call the exported function typedef int (*ExportedFunc)(int a, int b); ExportedFunc func = (ExportedFunc) procAddr; int result = func(1,2); ### 回答2: 在Windows下,可以使用LoadLibrary函数一个dll文件。 代码示例: ```cpp #include <windows.h> // 定义导出接口的函数指针类型 typedef void (*MyFunction)(); int main() { // dll文件 HMODULE hDll = LoadLibrary("example.dll"); if (hDll == NULL) { // 失败处理 return -1; } // 获取导出接口的函数指针 MyFunction myFunc = (MyFunction)GetProcAddress(hDll, "MyFunction"); if (myFunc == NULL) { // 获取函数指针失败处理 // 也可使用FreeLibrary来释放dll文件 FreeLibrary(hDll); return -1; } // 调用导出接口函数 myFunc(); // 释放dll文件 FreeLibrary(hDll); return 0; } ``` 在上面的示例,我们使用LoadLibrary函数来名为"example.dll"的dll文件,并判断是否成功。然后,使用GetProcAddress函数来获取导出接口函数"MyFunction"的函数指针,如果获取成功,则可以调用该函数指针来执行相应的操作。最后,使用FreeLibrary函数来释放已dll文件。 需要注意的是,代码的"HMODULE"和"MyFunction"是Windows API的数据类型和函数指针类型的定义,需要包含"windows.h"头文件来进行声明。在实际使用,需要根据具体的dll文件和导出接口函数名称进行修改。 ### 回答3: 在Windows,可以使用LoadLibrary函数一个DLL,并使用GetProcAddress函数来导出DLL的接口。 以下是一个示例代码来说明这个过程: ```cpp #include <iostream> #include <windows.h> // 定义DLL的函数指针类型 typedef int (*AddFunction)(int, int); int main() { // DLL HMODULE hDLL = LoadLibrary("myDLL.dll"); if (hDLL == nullptr) { std::cout << "无法DLL" << std::endl; return 1; } // 导出DLL的接口 AddFunction addFunc = reinterpret_cast<AddFunction>(GetProcAddress(hDLL, "Add")); if (addFunc == nullptr) { std::cout << "无法导出接口" << std::endl; return 1; } // 使用导出的接口 int result = addFunc(10, 20); std::cout << "调用DLL的Add函数的结果为:" << result << std::endl; // 卸DLL FreeLibrary(hDLL); return 0; } ``` 在这个示例代码,首先使用LoadLibrary函数来一个名为"myDLL.dll"的DLL文件。接着使用GetProcAddress函数来获取DLL导出的名为"Add"的函数指针,并将其强制换为AddFunction类型。然后可以使用这个函数指针来调用DLL的"Add"函数,并获取其结果。最后使用FreeLibrary函数来卸DLL。 请注意,代码DLL名称和接口名称应该替换为实际使用DLL文件和函数名称。在编译时,还需要将这个代码与相应的导入库链接起来。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值