c++显式加载dll并使用DLL的类 「爱情、让人受尽委屈。」 2022-07-14 03:41 979阅读 1赞 转载自: [http://blog.163.com/tianjunqiang666@126/blog/static/8725911920121064573594/][http_blog.163.com_tianjunqiang666_126_blog_static_8725911920121064573594] 首先需要强调,当使用某个类时一般目的有二:实例化成对象或者继承它产生新类。 对于前者,我们可以构造一个抽象类(java里的接口)来连接调用方和DLL。 // Interface.h 公共文件/ 公共接口 **\[cpp\]** [view plain][] [copy][view plain] [![在CODE上查看代码片][CODE]][CODE_CODE] [![派生到我的代码片][ico_fork.svg]][ico_fork.svg 1] 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 Interface\* Export(**void**); // Interface.cpp 被调用方文件 // 注意下面的代码并不是实现 Interface 类,而是因为联系紧密才写在这。 **\[cpp\]** [view plain][] [copy][view plain] [![在CODE上查看代码片][CODE]][CODE_CODE] [![派生到我的代码片][ico_fork.svg]][ico_fork.svg 1] 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][view plain] [![在CODE上查看代码片][CODE]][CODE_CODE] [![派生到我的代码片][ico_fork.svg]][ico_fork.svg 1] 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][view plain] [![在CODE上查看代码片][CODE]][CODE_CODE] [![派生到我的代码片][ico_fork.svg]][ico_fork.svg 1] 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][view plain] [![在CODE上查看代码片][CODE]][CODE_CODE] [![派生到我的代码片][ico_fork.svg]][ico_fork.svg 1] 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_7xs15g.com1.z0.glb.clouddn.com_Interface.zip] 转自:http://blog.csdn.net/xiamentingtao/article/details/51052925 [http_blog.163.com_tianjunqiang666_126_blog_static_8725911920121064573594]: http://blog.163.com/tianjunqiang666@126/blog/static/8725911920121064573594/ [view plain]: http://blog.csdn.net/xiamentingtao/article/details/51052925# [CODE]: https://code.csdn.net/assets/CODE_ico.png [CODE_CODE]: https://code.csdn.net/snippets/1633727 [ico_fork.svg]: https://code.csdn.net/assets/ico_fork.svg [ico_fork.svg 1]: https://code.csdn.net/snippets/1633727/fork [http_7xs15g.com1.z0.glb.clouddn.com_Interface.zip]: http://7xs15g.com1.z0.glb.clouddn.com/Interface.zip
相关 [SQLite DLL加载失败]——解决DLL库加载问题的方法详解 \[SQLite DLL加载失败\]——解决DLL库加载问题的方法详解 在开发过程中,你可能会遇到\[SQLite DLL加载失败\]这样的问题。当你尝试运行一个应用程序或者 ゞ 浴缸里的玫瑰/ 2024年03月25日 23:36/ 0 赞/ 83 阅读
相关 ClassLoader:类的隐式加载和显式加载 一、背景 > 类加载具有传递性:如当需要加载一个类时,JVM 默认会使用(当前需要使用此类的)调用者 Class 对象的 ClassLoader 来加载此类;举例:类 A 缺乏、安全感/ 2024年03月25日 20:34/ 0 赞/ 80 阅读
相关 C#创建并使用DLL文件 一.创建DLL文件 1.新建C\类库项目 ![在这里插入图片描述][watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_tex 骑猪看日落/ 2022年10月16日 06:21/ 0 赞/ 289 阅读
相关 MFC静态加载dll和动态加载dll示例 一、静态加载DLL 函数的定义和使用方法: 第一步: 运行AppWizard,定义项目名为mydll,选择MFC AppWizard(dll),而不是MFC App 古城微笑少年丶/ 2022年08月27日 04:49/ 0 赞/ 954 阅读
相关 JAVA动态加载dll任意路径加载dll package com.ctl.test; import java.io.File; import java.io.FileOutputStr 向右看齐/ 2022年08月24日 00:57/ 0 赞/ 583 阅读
相关 加载dll以及卸载dll相关的几个API 普及一下知识: (1)LoadLibrary函数将指定的DLL模块加载到进程的地址空间中。 调用成功,返回指定DLL文件的句柄,DLL句柄用来标识一个DLL文件。 调用失 Myth丶恋晨/ 2022年08月13日 15:51/ 0 赞/ 337 阅读
相关 c++显式加载dll并使用DLL的类 转载自: [http://blog.163.com/tianjunqiang666@126/blog/static/8725911920121064573594/][ 以你之姓@/ 2022年07月15日 03:15/ 0 赞/ 254 阅读
相关 c++显式加载dll并使用DLL的类 转载自: [http://blog.163.com/tianjunqiang666@126/blog/static/8725911920121064573594/][ 「爱情、让人受尽委屈。」/ 2022年07月14日 03:41/ 1 赞/ 980 阅读
相关 java 加载dll文件 Dll有两类:Java所依赖的dll以及dll所依赖的dll。Java中加载dll的方式也有两种:(1)通过调用System.loadLibrary(String 蔚落/ 2022年05月15日 03:09/ 0 赞/ 727 阅读
相关 C# VS 调试 动态加载的 DLL 原文:https://www.cnblogs.com/DasonKwok/p/10510218.html 在这篇文章的底部,有提供示例的Demo,可以参考一下哦,拿来直接就可 - 日理万妓/ 2022年01月08日 02:27/ 0 赞/ 314 阅读