C语言dll文件的说明以及生成、使用方法

您所在的位置:网站首页 c语言编译dll C语言dll文件的说明以及生成、使用方法

C语言dll文件的说明以及生成、使用方法

2024-03-24 10:21| 来源: 网络整理| 查看: 265

  最近在搞一些小项目,由于要涉及到跟其它语言进行交互,动态链接库变成了不二的选择。为此也查阅了很多资料,将动态链接库的相关知识在此做一个整理。

一、动态链接库概述

  动态链接库(Dynamic Link Library )是一种不可执行的二进制程序文件,它允许多个程序共享执行特殊任务所必需的代码和其他资源。Windows 中,DLL 多数情况下是带有 ".dll" 扩展名的文件,但也可能是 ".ocx"或其他扩展名;Linux系统中常常是 ".so" 的文件。动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 文件中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。使用动态链接库可以更为容易地将更新应用于各个模块,而不会影响该程序的其他部分。是开发大型项目必不可少的部分。

二、优缺点

优点:(1)节省内存和代码重用:当多个程序使用同一个函数库时,DLL可以减少在磁盘和物理内存中加载代码的重复量,且有助于代码的重用。

     (2)模块化:DLL有助于促进模块式程序开发。模块化允许仅仅更改几个应用程序共享使用的一个DLL中的代码和数据而不需要更改应用程序自身。适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。这种模块化的基本形式允许如Microsoft Office、Microsoft Visual Studio、甚至windows自身这样大的应用程序使用较为紧凑的补丁和服务包。

       (3)扩展了应用程序的特性,使用dll文件可以使得应用程序能很方便的进行功能的扩展,很多程序的插件机制就是通过dll文件实现的。

     (4)可以用多种语言来编译和调用,由于各种语言都有自己独特的开发优势,在处理某类事务方面具有着独特的优势,所以在多种语言编程的过程中,可以利用dll文件作为桥梁,可以发挥多种语言的优点。

缺点:DLL Hell:即DLL地狱,指几个应用程序在使用同一个共享的DLL库时发生版本冲突。

  究其原因,八个字:成也共用,败也共用。因为DLL Hell正是由于动态链接库可与其他程序共用函数、资源所导致。

  主要有两种情况:

  设想这样一个场景:程序A会使用1.0版本的动态链接库X,则在程序A安装到系统时,会同时安装该1.0版本的动态链接库X。假设另一个程序B也会使用到动态链接库X,那么程序B直接复制到硬盘中即可正常运行,因为动态链接库已经存在于系统中。然而有一天,另一程序C也要使用动态链接库X,但是由于程序C开发的时间较晚,其需要较新版本---2.0版本的动态链接库X。则在程序C被安装到系统时,2.0版本的动态链接库X 也必须随之安装到系统中,此时系统中1.0版本的动态链接库将被2.0版本所取代(替换)。

  情况1:新版本的动态链接库不兼容旧版本。如,A何B需要X所提供的功能,在升级到2.0后,新版本的X竟然把此功能取消了(很难想象吧,呵呵但有时候就是如此....)。则此时虽然C能正常运行,但A和B均无法工作了。

  情况2:新版本的动态链接库兼容旧版本,但是存在一个bug。

三、入口点

  就跟应用程序的main函数一样,dll文件也有入口函数,叫做DllMain(),它的原型是这样的:

1 BOOL APIENTRY DllMain( 2 HANDLE hModule, // DLL模块的句柄 3 DWORD ul_reason_for_call, // 调用本函数的原因 4 LPVOID lpReserved // 保留 5 ) { 6 switch (ul_reason_for_call) 7 { 8 case DLL_PROCESS_ATTACH: 9 //进程正在加载本DLL 10 break; 11 case DLL_THREAD_ATTACH: 12 //一个线程被创建 13 break; 14 case DLL_THREAD_DETACH: 15 //一个线程正常退出 16 break; 17 case DLL_PROCESS_DETACH: 18 //进程正在卸载本DLL 19 break; 20 } 21 return TRUE; //返回TRUE,表示成功执行本函数 22 }

  入口点函数只应执行简单的初始化任务,不应调用任何其他 DLL 加载函数或终止函数。例如,在入口点函数中,不应直接或间接调用 LoadLibrary 函数或LoadLibraryEx 函数。此外,不应在进程终止时调用 FreeLibrary函数。

四、生成DLL文件

  下面来生成一个DLL文件,为方便起见,只定义一个简单函数。

  生成DLL文件需要用到两个文件,一个头文件,dll_add.h,和一个源文件,dll_add.c

  头文件内容:

1 #ifndef _DLL_DEMO_H_ 2 #define _DLL_DEMO_H_ 3 #ifdef DLLDEMO_EXPORTS 4 #define DLL_DEMO _declspec( dllexport ) 5 #else 6 #define DLL_DEMO _declspec(dllimport) 7 #endif 8 extern "C" DLL_DEMO int Add(int a, int b); 9 #endif

  源文件内容:

1 #include "dll_demo.h" 2 3 int Add(int a, int b) 4 { 5 return (a + b); 6 }

  这里因为不需要对函数载入与卸载作特殊处理,所以可以不使用入口函数。

  使用的是vs2015,在debug模式或者release模式下调试后会在相应目录下生成dll文件,即可使用。

五、调用DLL文件

  生成DLL自然是为了调用,调用DLL有两种方式。

静态调用:使用.h+.lib+.dll

1 #include 2 #include 3 #include "DLL_DEMO.h" 4 using namespace std; 5 #pragma comment(lib, "DLL_DEMO.lib") 6 7 extern "C" _declspec(dllimport) int Add(int a, int b); 8 int main(int argc, char *argv[]) 9 { 10 cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3