当前位置:   article > 正文

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

c语言dll

动态链接库

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

  • 节省内存和代码重用:当多个程序使用同一个函数库时,可以减少在磁盘和物理内存中加载代码的重复量,有助于代码的重用。
  • 模块化:DLL有助于促进模块式程序开发。模块化允许仅仅更改几个应用程序共享使用的一个DLL中的代码和数据而不需要更改应用程序自身。适用于大规模的软件开发,使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开发和测试。这种模块化的基本形式允许如Microsoft Office、Microsoft Visual Studio、甚至windows自身这样大的应用程序使用较为紧凑的补丁和服务包。扩展了应用程序的特性,使用dll文件可以使得应用程序能很方便的进行功能的扩展,很多程序的插件机制就是通过dll文件实现的。
  • 可以用多种语言来编译和调用:由于各种语言都有自己独特的开发优势,在处理某类事务方面具有着独特的优势,所以在多种语言编程的过程中,可以利用dll文件作为桥梁,可以发挥多种语言的优点。

 缺点:DLL Hell:即DLL地狱,指几个应用程序在使用同一个共享的DLL库时发生版本冲突。
究其原因,成也共用,败也共用。因为DLL Hell正是由于动态链接库可与其他程序共用函数、资源所导致。

新建动态库

 

      ps:__declspec(dllexport)的作用:就是为了省掉在DEF文件中手工定义导出哪些函数的一个方法。当然,如果你的DLL里全是C++的类的话,你无法在DEF里指定导出的函数,只能用__declspec(dllexport)导出类。
       注:extern "C"是可选的,extern "C"是为了保证导出的DLL函数名不发生变化。如果写了extern "C",那么导出和导入都要写,要保证一致。如果要导出的是类,不能在类名前加extern "C",切记切记!!编译不会通过的。
如果在新建dll的时候选择空白的文件(即不用vs自带的帮你生成),注意一定要自己手动添加def文件。否则生成不了lib文件。

       就跟应用程序的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: //进程正在加载本DLL
  9. break;
  10. case DLL_THREAD_ATTACH://一个线程被创建
  11. break;
  12. case DLL_THREAD_DETACH://一个线程正常退出
  13. break;
  14. case DLL_PROCESS_DETACH://进程正在卸载本DLL
  15. break;
  16. }
  17. return TRUE; //返回TRUE,表示成功执行本函数
  18. }

调用DLL有两种方式

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

  1. #include <windows.h>
  2. #include <iostream>
  3. #include "DLL_DEMO.h"
  4. using namespace std;
  5. #pragma comment(lib, "DLL_DEMO.lib")
  6. extern "C" _declspec(dllimport) int Add(int a, int b);
  7. int main()
  8. {
  9. cout << Add(2, 3) << endl;
  10. system("pause");
  11. return 0;
  12. }

动态调用:仅使用dll文件 

把头文件和lib文件、dll文件都放到跟源文件同一目录下即可使用。当然,路径可以重新设置。

  1. #include <windows.h>
  2. #include <iostream>
  3. using namespace std;
  4. typedef int (*AddFunc)(int a, int b);
  5. int main()
  6. {
  7. HMODULE hDll = LoadLibrary(L"DLL_DEMO.dll");
  8. if (hDll != NULL)
  9. {
  10. AddFunc add = (AddFunc)GetProcAddress(hDll, "Add");
  11. if (add != NULL)
  12. {
  13. cout<<add(2, 3)<<endl;
  14. }
  15. FreeLibrary(hDll);
  16. }
  17. }

        在字符串前加一个L作用: unicode字符集是两个字节组成的。L告示编译器使用两个字节的 unicode 字符集。可以使用dll来实现类和变量的共享,还可以实现内存共享

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/204270
推荐阅读
相关标签
  

闽ICP备14008679号