博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MFC中的DLL、LIb文件的创建、使用
阅读量:5337 次
发布时间:2019-06-15

本文共 3702 字,大约阅读时间需要 12 分钟。

 动态链接库Dynamic-Linked Lib 的创建与使用

  动态链接库(Dynamic Link Library 或者 Dynamic-link Library,缩写为 DLL),是微软公司在微软Windows操作系统中,实现共享函数库概念的一种方式。这些库函数的扩展名是 ”.dll"。

  动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 文件中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。使用动态链接库可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。例如,您有一个大型网络游戏,如果把整个数百MB甚至数GB的游戏的代码都放在一个应用程序里,日后的修改工作将会十分费时,而如果把不同功能的代码分别放在数个动态链接库中,您无需重新生成或安装整个程序就可以应用更新。;系统中常常是 ".so" 的文件表示是动态链接库。

  1. 扩展了应用程序的特性;
  2. 可以用许多种编程语言来编写;
  3. 简化了软件项目的管理;
  4. 有助于节省内存;
  5. 有助于资源共享;
  6. 有助于应用程序的本地化;
  7. 有助于解决平台差异;
  8. 可以用于一些特殊的目的。Windows 使得某些特性只能为 DLL 所用。

   VS2013在创建DLL时提供了很好的便捷性,通过新建项目--Win32项目: 选中DLL,以及导出符号,则MFC会自动生成Win32Dll2.h和Win32Dll2.cpp 两个文件,.h文件是要导出内容的声明文件,可以直接和DLL文件一起发送公开。如下图:

           

  

  修改.cpp文件中按照给出的实例添加自己的程序:

  可以在DLL中添加:变量,函数,类

1 // Win32Dll2.cpp : 定义 DLL 应用程序的导出函数。 2 // 3 #include "stdafx.h" 4 #include "Win32Dll2.h" 5 // 这是导出变量的一个示例 6 WIN32DLL2_API int nWin32Dll2=0; 7 // 这是导出函数的一个示例。 8 WIN32DLL2_API int fnWin32Dll2(void) 9 {10     return 42;11 }12 // 这是已导出类的构造函数。13 // 有关类定义的信息,请参阅 Win32Dll2.h14 CWin32Dll2::CWin32Dll2()15 {16     return;17 }18 WIN32DLL2_API int addByDll(int a, int b)19 {20     return a + b;21 }

  修改.h文件,添加自己函数的dll声明:

1 // 下列 ifdef 块是创建使从 DLL 导出更简单的 2 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 WIN32DLL2_EXPORTS 3 // 符号编译的。在使用此 DLL 的 4 // 任何其他项目上不应定义此符号。这样,源文件中包含此文件的任何其他项目都会将 5 // WIN32DLL2_API 函数视为是从 DLL 导入的,而此 DLL 则将用此宏定义的 6 // 符号视为是被导出的。 7 #ifdef WIN32DLL2_EXPORTS 8 #define WIN32DLL2_API __declspec(dllexport) 9 #else10 #define WIN32DLL2_API __declspec(dllimport)11 #endif12 13 // 此类是从 Win32Dll2.dll 导出的14 class WIN32DLL2_API CWin32Dll2 {15 public:16     CWin32Dll2(void);17     // TODO:  在此添加您的方法。18 19 };20 extern WIN32DLL2_API int nWin32Dll2;21 WIN32DLL2_API int fnWin32Dll2(void);22 WIN32DLL2_API int addByDll(int a, int b);

  编译Win32Dll2项目,在编译C++DLL之前,需要做以下配置(项目右键项目属性):项目属性--[C/C++]--高级:修改“编译为”的值为"C++",这样创建C++调用的动态DLL。

  则再解决方案的Debug目录下面生成如下文件:其中.dll文件,以及.lib文件最重要 。

  .dll文件最终要放在被调用项目的Debug目录下面(随exe文件同目录位置)。

  .lib文件需要包含如被调用项目中。

  .h文件也提供给用户,用于包含在被调用项目的文件目录中。因为一般DLL会提供一个头文件,在此文件中提供DLL导出函数原型的声明.h文件这样便于DLL方便调用。

  

  DLL库的使用:

  创建DLL测试工程:dllTest, Win32控制台项目

  使用DLL步骤如下:

  (1)将DLL提供的头文件XXX.h放置在测试项目中的物理文件存储位置。

      在测试项目中将此文件包含进来:在放置的合适的逻辑位置右键--添加--已有文件,添加即可。

    或者:1.当不需要模块划分,直接放置在了测试项目文件根目录下面:

      相对路径方式再使用的文件中直接#include“..\..XXX.h”。 直接调用。(需要考虑相对路径问题)

    或者:2. 当需要模块划分,文件放置在项目文件根目录中下的子模块的文件夹下面:

      修改“附加包含目录”:项目属性--配置属性--【C/C++】--常规:附加包含目录。 即添加.h文件所在的目录。 然后直接在需要使用的文件中#include“XXX.h”,从而不需要考虑相对路径的问题

  (2)将DLL提供的XXX.lib文件添加到测试项目中。

    1. 添加文件引用的lib静态库路径:

      修改“附加包含目录”:项目属性--配置属性--连接器--常规:附加库目录。 即添加.lib文件所在的目录

    2. 然后添加测试工程引用的lib文件名:

      项目属性---配置属性---链接器---输入---附加依赖项:加上lib文件名。

  (3)添加工程引用的dll动态库,添加到Debug(exe文件的相同目录下)

    把引用的dll放到工程的可执行文件所在的目录下。如果不放置在此目录下,会出现如下情况:

    

    测试程序如下:

#include "stdafx.h"#include 
#include "Win32Dll2.h"//#include "Win32"using namespace std;////extern int addByDll(int a, int b);//extern int subByDll(int a, int b);int _tmain(int argc, _TCHAR* argv[]){ cout << "11 + 8 = " << addByDll(11, 8) << endl; system("pause"); return 0;}

  编译通过后,执行:

  

 

  如果不采用MFC自动提供的方式,如果直接写,则同样有生成Dll和lib文件,但是没有.h文件。

  则再CPP文件中直接定义:

_declspec(dllexport) int addByDll(int a, int b){    return a + b;}_declspec(dllexport)  int subByDll(int a, int b){    return a - b;}

 

2.  然后在测试工程中如上述添加lib,以及Dll方式处理。

  在需要引用的位置使用如下声明,因为在编译的时候,头文件不参与编译,只编译源文件。 __declspec(dllimport) 则是用来定义从动态链接库中的引用声明。

 .h使用文件如下添加从动态链接库的引用声明。

#ifdef WIN32DLL2_EXPORTS #define WIN32DLL2_API __declspec(dllexport) #else #define WIN32DLL2_API __declspec(dllimport) #endif WIN32DLL2_API int addByDll(int a, int b);WIN32DLL2_API int subByDll(int a, int b);

  

3. DLL可以导出C++类 

转载于:https://www.cnblogs.com/icmzn/p/5727165.html

你可能感兴趣的文章
HAL层三类函数及其作用
查看>>
Odoo 去掉 恼人的 "上午"和"下午"
查看>>
web@h,c小总结
查看>>
java编程思想笔记(一)——面向对象导论
查看>>
Data Structure 基本概念
查看>>
Ubuntu改坏sudoers后无法使用sudo的解决办法
查看>>
NEYC 2017 游记
查看>>
[搬运] 写给 C# 开发人员的函数式编程
查看>>
Python之旅Day14 JQuery部分
查看>>
core--线程池
查看>>
redux-effect
查看>>
Swift和OC混编
查看>>
Android轻量级的开源缓存框架ASimpleCache
查看>>
他山之石:加载图片的一个小问题
查看>>
shell - 常识
查看>>
mssql sqlserver 使用sql脚本 清空所有数据库表数据的方法分享
查看>>
分层图最短路【bzoj2763】: [JLOI2011]飞行路线
查看>>
linux下编译复数类型引发的错误:expected unqualified-id before '(' token
查看>>
codeforces 1041A Heist
查看>>
字典常用方法
查看>>