(1)DLL的构成

每个应用程序都有一个入口函数WinMain,而每个DLL也有一个入口函数DllMain。DLL跟应用程序一样都含有资源、数据段和代码段。DLL跟应用程序的差别主要是DLL有符号输入表和符号输出表,以方便应用程序调用DLL中的函数。

因为DLL是由应用程序加载的,所以它本身没有虚拟的内存地址空间,它使用的是加载它的应用程序的地址空间。这种加载分为隐式和显式两种方式。将在后面叙述。

(2)创建MFC DLL

A,VC6新建一个工程MFCDLL,类型为MFC  AppWizard(dll),具体选项为Regular DLL using shared MFC DLL。我们在MFCDLL.cpp的末尾添加实现代码如下:

int sum(int a,int b)
{
        return a+b;
}
int sub(int a,int b)
{
        return a-b;
}

B,使用时,动态链接库的函数申明是写在def文件中,编译器根据这个文件的函数申明来生成lib文件和dll文件。我们只需要在MFCDLL.def文件的末尾添加代码如下:

sum  @1;
sub   @2;   //后面表示函数的序号

以上两步完成后,即可编译生成DLL了,总共生成MFCDLL.dll和MFCDLL.lib两个文件。DLL本身不能运行,所以还需要一个测试程序。

C,隐式加载MFC DLL并测试

用VC创建一个对话框工程testDlg,加上“测试加法”“测试减法”两个按钮。隐式加载需要在testDlg头文件头部添加代码申明:

#pragma comment(lib,"MFCDLL")
int sum(int a,int b);
int sub(int a,int b);

编译时,需要将MFCDLL.lib拷贝到test工程目录下(dll可有可没有),否则会有错误提示:cannot open file "MFCDLL.lib"。在保证编译成功后,直接点击运行EXE也是无法成功的,会提示无法找到MFCDLL.dll文件。这个时候需要将MFCDLL.dll拷贝到跟EXE同层的目录。

给对话框按钮添加的代码如下:

void CDLLtestDlg::OnSum()
{
      int value = sum(10,4);
      CString string;
      string.Format("sum value is %d",value);
      MessageBox(string);
}

void CDLLtestDlg::OnSub()
{
      int value = sub(10,4);
      CString string;
      string.Format("sub value is %d",value);
      MessageBox(string);
}

D,显式加载MFC DLL并测试

用VC创建一个对话框,放置如上的“测试加法”和“测试减法”的按钮。采用显式加载DLL法,需要添加一个句柄来存储加载DLL的返回值,还要定义带参数的指针类型存储获得的两个函数地址typedef int (*PFUNC)(int,int);,在对话框头文件的类中如下:

public:
 HMODULE hDllLib;
 PFUNC m_pSum;
 PFUNC m_pSub;

在对话框的初始化中添加DLL加载过程:

hDllLib = LoadLibrary("MFCDLL.dll");   
 if(hDllLib == NULL)
 {
       MessageBox("dll load error");
       return FALSE;
 }

m_pSum = (PFUNC)GetProcAddress(hDllLib,"sum"); //强制类型转换一定要加,GetProcAddress默认返回不带参数的函数指针
 m_pSub = (PFUNC)GetProcAddress(hDllLib,"sub");

为了完整性,在对话框的WM_DESTORY消息的响应函数OnDestroy()中添加:

FreeLibrary(hDllLib);

这样,两个按钮的操作如下:

void CMFCDLLtest2Dlg::OnSum()
{

int value = m_pSum(10,4);
      CString string;
      string.Format("sum value is %d",value);
      MessageBox(string);
}

void CMFCDLLtest2Dlg::OnSub()
{
      int value = m_pSub(10,4);
      CString string;
      string.Format("sub value is %d",value);
      MessageBox(string);
}

动态加载不需要LIB文件,只要把DLL文件放在EXE同目录下即可运行。

(3)WIN32 DLL说明

WIN32 DLL与MFC DLL的差别在于它的DllMain不是打包的,是可见的。它同样其中定义函数实体,不过在头文件中都需要申明(申明语句是特定的,如extern "C" __declspec( dllexport ) )。缺省的入口函数如下:

BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
       switch (ul_reason_for_call)
       {
               case DLL_PROCESS_ATTACH:    //进程被创建
               case DLL_THREAD_ATTACH:      //线程被创建
               case DLL_THREAD_DETACH:      //线程被终止
               case DLL_PROCESS_DETACH:   //进程被终止
               break;
       }
       return TRUE;
}

DllMain负责初始化和结束工作。

hModule是动态库被调用时所传递过来的一个指向自己的句柄;

ul_reason_for_call是一个说明动态库被调用原因的标志。当进程或者线程装载、卸载动态链接库的时候,操作系统便调用入口函数。

lpReserved是一个被系统保留的参数

理解以上之后,就需要考虑输出函数的实现方法。

(4)创建WIN32 DLL

A,用VC6创建一个WIN32  DLL工程WIN32DLL,可以看出它默认用WIN32DLL_API这个符号输出一个变量nWIN32DLL 和一个函数fnWIN32DLL,而WIN32DLL_API相当于__declspec(dllexport)。类似,在对话框头文件中添加输出申明,同时需要特别关注的是在申明和定义前都要加extern "C"关键字,如果不加在隐式调用和显式调用时会出现异常状况:

extern "C" WIN32DLL_API int sum(int a,int b);
extern "C" WIN32DLL_API int sub(int a,int b);

在对话框C文件完成函数体:

extern "C" WIN32DLL_API int sum(int a,int b)
{
      return a+b;
}

extern "C" WIN32DLL_API int sub(int a,int b)
{
      return a-b;
}

编译就生成对应的LIB和DLL。

B,隐式加载WIN32 DLL并测试

利用第(2)步同样的隐式调用测试程序,就可以测试这个DLL。有点差别,就是头文件前也要加extern "C",否则编译错误。如下:

#pragma comment(lib,"win32")
exter

MFC动态链接库和WIN32动态链接库区别:

通过MFC创建DLL你必须链接MFC库,无论动态或静态,优点是如CString等,促使开发方便,缺点是静态链接臃肿,动态链接必须附带mfc库,部署不方便。mfc使用mfc类库建立的dll 而win32是用win32函数建立的dll,
win32定义为 win98于win2000系统库函数,用的是标准的C接口


而mfc是对win32的进一步封装,他是从CWINAPP派生的,接口可以是扩展库 也可以是规则库
他们的通用性有点区别,win32更广泛,而mfc dll更方便,

如果你只想关心dll的实现,不想花心思去设计框架,MFC Dll就帮你做了。
如果你觉得MFC好烦,什么细节都隐藏,到处都是宏定义,又不知所云;再者自己也想练练手,自己搭建一砖一瓦,那么选择Win32 Dll就是了。至于那些扩展的类,只要加上需要的头文件就能用了,没什么差别的。

MFC动态链接库和WIN32动态链接库 及区别相关推荐

  1. 使用vs2019创建win32动态链接库

    划水了一周,今天去公司总算是给我分配任务了,不过吧啦吧啦说了半天我还是一头雾水.项目经理让带我的人把类和接口定义好,其他的由我自己实现,我也不知道为啥要用win32动态链接库,百度了一下好像是为了节约 ...

  2. 为什么要动态链接,动态链接库和静态连接的区别与优势

    本文摘抄于程序员的自我修养-链接装载与库7.1节,这段写的很好,直接拿过来来收藏 http://www.wq3028.top/technology/compile/20180727124/ 静态链接使 ...

  3. 动态链接库和静态库的区别

     动态链接库.静态库.import库区别 动态链接库(Dynamic Linked Library): Windows为应用程序提供了丰富的函数调用,这些函数调用都包含在动态链接库中.其中有3个最 ...

  4. VS2008创建win32动态链接库图文流程

    本文原创版权归 csdn zwlforever 所有,此处纯粹共享,如有再转,请以如下方式显示标明原创作者及出处,以示尊重! 作者:zwlforever 原文:http://blog.csdn.net ...

  5. 【基础】动态链接库/静态链接库的区别

    一.静态链接库与动态链接库的简介 C或C++程序从源文件到生成可执行文件需经历 4 个阶段 分别为预处理.编译.汇编和链接. 链接阶段所要完成的工作,是将同一项目中各源文件生成的目标文件和程序中用到的 ...

  6. ATL CLR MFC Win32 常规 的区别

    ATL用于编写COM程序,CLR是.NET的公共语言运行库,MFC是指MFC类库,MFC程序是用这些类库做出的程序,WIN32常规就是不用 MFC,使用API函数编的程序. MFC.ATL和CLR是V ...

  7. Gazebo添加模型并控制模型运动作为动态障碍物(Ubuntu16.04, Gazebo7.16),附录动态链接库和静态链接库区别

    Gazebo作为一个运动仿真环境,可以直接加载编写好的机器人模型(如TIAGo和Yumi等),也可以自己构建多个运动模型,不过稍有难度.在构建复杂运动模型前,我们需要熟悉gazebo模型设置以及插件编 ...

  8. .h头文件 .lib动态链接库文件 .dll 动态链接库

    .h头文件是编译时必须的,lib是链接时需要的,dll是运行时需要的. 附加依赖项的是.lib不是.dll,若生成了DLL,则肯定也生成 LIB文件.如果要完成源代码的编译和链接,有头文件和lib就够 ...

  9. python 如何封装dll_Python的扩展接口[2] - 动态链接库DLL[0] - 动态链接库及辅助工具...

    动态链接库/ Dynamic Link Library 目录 1动态链接库简介/ DLL Introduction 动态链接库(Dynamic Link Library, DLL),是微软在Windo ...

  10. VC学习笔记---ATL MFC CLR三个库的区别

    MFC.ATL和CLR是VC2005内置的三大库,涵盖了Windows的各种开发方法和开发应用.当然关于C++开发的库不止这三个,不过这三个是微软推荐. 从编程所处层次而言,WIN32为最底层,其次是 ...

最新文章

  1. 推荐7款Mac上能极大提高效率的软件,建议收藏!
  2. Go的变量到底在堆还是栈中分配
  3. CSP CCF 201709-2 公共钥匙盒(C++)满分代码,有注释
  4. (转)Android属性设置android:noHistory=true
  5. Kafka刚开启就秒退
  6. vivado中bit文件怎么没有生成_「干货」FPGA设计中深度约束技巧及调试经验总结...
  7. js html模板生成图片不显示,网页中图片不显示问题
  8. NoSQL Manager for MongoDB 连接配置
  9. 基于持续集成的轻量级接口自动化测试
  10. django之开发环境关于settins.py里面的DEBUG的设置和静态文件的关系
  11. rtmp协议java实现_RTMP 协议的一个 Java 实现:Flazr
  12. 兼容树莓派CM4定制产品
  13. 小白刷LeeCode(算法篇)
  14. DTP,VTP,链路聚合
  15. VS2005/SQL2005等原版镜像高速下载
  16. 部署 docker 容器虚拟化平台
  17. python概率编程_Python概率编程库PyMC应用案例二则,pymc应用案例
  18. 【pyqt】自制的图片裁剪分割器
  19. checkpoint = torch.load(args.state_dict) ->RuntimeError: CUDA error: out of memory
  20. 从公司管理到IT审计-网摘

热门文章

  1. layui表格使用复选框批量删除_layui表格数据复选框回显设置方法,表格复选框...
  2. android倒计时像音乐,Android实现倒计时的几种方式
  3. php 验证链接,PHP判断链接是否有效 的方法
  4. cookie实现上次访问时间
  5. php路径跳转include,PHP中include路径的解决方法汇总
  6. python3发送邮件_Python3发送电子邮件
  7. 双调欧几里得旅行商问题_遗传模拟退火算法求解旅行商(TSP)问题MATLAB代码讲解...
  8. mysql 部署最佳实践_MySQL安装脚本最佳实践
  9. (6)二进制文件方式部署Kubernetes高可用集群----------安装Docker Engine
  10. python脚本转换为EXE文件