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

来源:互联网 发布:中国网络诗歌网 编辑:程序博客网 时间:2024/04/29 16:28
转载自:


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

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

// 下列 ifdef 块是创建使从 DLL 导出更简单的// 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 INTERFACE_EXPORTS// 符号编译的。在使用此 DLL 的// 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将// INTERFACE_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的// 符号视为是被导出的。#ifdef INTERFACE_EXPORTS#define INTERFACE_API __declspec(dllexport)#else#define INTERFACE_API __declspec(dllimport)#endif#pragma onceclass Interface{public:virtual void ShowMsg() = 0; // 将调用方需要调用的成员函数声明成纯虚函数virtual ~Interface(){};// 抽象类的虚析构函数};extern "C" INTERFACE_API Interface* Export(void);
// Interface.cpp 被调用方文件////////////////////////////////////////////////


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

// Interface.cpp : 定义 DLL 应用程序的导出函数。//#include "stdafx.h"#include "Interface.h"#include <iostream>#include "test.h"// 通过导出函数形式向调用方提供指向派生类对象的基类指针Interface* Export(void){return (Interface*)new Test();}

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

#pragma once#include "Interface.h"#include <string>class Test :public Interface{public:Test();virtual ~Test();virtual void ShowMsg(void);private:std::string s;};

// Test.cpp 被调用方文件////////////////////////////////////////


// 类的实现
#include "stdafx.h"#include "test.h"#include <iostream>Test::Test(){s = "hello form dll";}Test::~Test(){std::cout << "destroy";}void Test::ShowMsg(){std::cout << s << std::endl;}


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

#include <Windows.h>#include <iostream>#include "Interface.h" // 包含抽象类从而使用接口// 在调用处添加如下代码using pExport = Interface* (*)(void); // 定义指向导出函数的指针类型int main(){HINSTANCE hDll = LoadLibrary("Interface.dll");// 加载DLL库文件,DLL名称和路径用自己的if (hDll == NULL){std::cout << "load dll fail \n";return -1;}pExport Get = (pExport)GetProcAddress(hDll, "Export");// 将指针指向函数首地址if (Get == NULL){std::cout << "load address fail \n";return -1;}Interface *t = Get();// 调用导出函数获得抽象类指针t->ShowMsg();// 通过该指针调用类成员函数delete t; // 释放DLL中生成的对象FreeLibrary(hDll); //释放库句柄system("pause");return 0;}


此时需要注意两点:

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

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

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

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

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

 
0 0
原创粉丝点击