C++ 中动态链接库–导入和导出的实例详解

C++ 中动态链接库--导入和导出的实例详解

动态链接库

动态链接库(Dynamic Link Library,简称 DLL)是一种共享库,可以在多个不同的应用程序中被使用,从而达到代码共享与节约程序的空间资源的目的。在C/C++ 中,链接器需要将每一个源文件的目标文件抽出来并重新组合成一个大的目标文件,该目标文件包含了完整代码,因此容易造成代码浪费和可执行程序文件过于庞大的问题。而使用动态链接库则可以很好地解决这些问题。

动态链接库的优点

  1. 程序模块化,容易维护,代码相互独立,便于分工协作开发。
  2. 能够共享代码,使程序更加轻巧,节省了硬盘空间和内存资源。
  3. 便于程序升级,只需将 DLL 文件替换即可,不影响主程序。
  4. 提高应用程序的运行速度,因为程序优先调用 DLL 文件中已编译好的函数代码,而不是自己编写的代码。

动态链接库的导入和导出

对于 DLL 文件,它有两种角色:导入库和导出库。导入库(.lib文件)是给应用程序使用的而导出库(.dll文件)是给程序员写 DLL 的时候使用的。导入库可以理解为使用 DLL 的“中介”,它负责维护和调用 DLL 函数的地址等信息,而导出库则负责将 DLL 中的函数暴露出来让外部使用。

导出例子

首先,我们需要定义一个导出函数,在 C++ 中则采用 extern "C" 关键字来指定导出函数的 C++ 风格(即取消了函数名的名称修饰),代码示例如下:

#ifdef EXPORTS
#define EXPORT_API extern "C" __declspec(dllexport)
#else
#define EXPORT_API extern "C" __declspec(dllimport)
#endif

EXPORT_API int add(int a, int b)
{
  return a + b;
}

该代码指定了导出函数 add,并且在 DLL 中使用 __declspec(dllexport) 来使其暴露。同时用 __declspec(dllimport) 来引用导出函数。

导入例子

然后我们需要编写一个测试程序来使用导出函数,代码示例如下:

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
  HINSTANCE hDll = LoadLibrary(TEXT("MyMathDLL.dll"));
  if (hDll)
  {
    FARPROC pAdd = GetProcAddress(hDll, "add"); //获取导出函数
    if (pAdd)
    {
      int a = 3;
      int b = 5;
      int c = ((int (__cdecl *)(int, int))pAdd)(a,b); //调用导出函数
      cout<<"a + b = "<<c<<endl;
    }
    else
      cout<<"Function add not found"<<endl;
    FreeLibrary(hDll);
  }
  else
    cout<<"Load DLL failed"<<endl;
  return 0;
}

该代码使用 LoadLibrary 函数加载 DLL,并使用 GetProcAddress 函数获取 DLL 中指定的导出函数 add。在获取到导出函数之后,通过强制转换成指针的方式来使用导出函数。最后,在使用完导出函数后,使用 FreeLibrary 函数将 DLL 卸载,释放内存空间。

以上就是使用 C++ 实现 DLL 中导入和导出的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 中动态链接库–导入和导出的实例详解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • 你真的了解java单例模式了吗?

    当我们在编写Java程序时,可能会需要某些类在整个程序运行周期内只能有一个实例被创建。这个时候,就可以采用单例(Singleton)模式。 单例模式是一种创建型设计模式。在单例模式中,一个类只允许有一个实例,而且该实例易于被外界访问。在很多情况下,对象如果被实例化多次可能会产生不必要的开销,如资源消耗、多次处理等。因此使用单例模式可以避免这种情况的产生。 下…

    other 2023年6月26日
    00
  • Java 找不到或无法加载主类的修复方法

    修复 Java 找不到或无法加载主类的方法 简介 当你在运行 Java 程序时,如果遇到“找不到或无法加载主类”的错误,这通常表示 JVM(Java 虚拟机)无法找到指定的主类。这种问题可以由于多种原因引起,但是通过以下方法可以修复它。 方法一:检查类路径 主类是 Java 程序的入口点,JVM 依靠类路径来找到主类。因此,首先检查类路径是否正确。 确保你已…

    other 2023年6月28日
    00
  • Ruby教程之注释、变量声明以及数组操作

    Ruby教程之注释、变量声明以及数组操作 注释 在Ruby中,注释用于向代码中添加说明性的文本,这些文本不会被解释器执行。注释可以帮助其他开发人员理解代码的功能和意图。 Ruby支持两种类型的注释: 单行注释:以#符号开头,从该符号后的所有内容都被视为注释。 示例: # 这是一个单行注释 puts \"Hello, World!\" # …

    other 2023年8月8日
    00
  • Xmind8 Pro 最新激活序列号

    Xmind8 Pro 最新激活序列号攻略 1. 确认Xmind8 Pro版本 在进行激活序列号之前,首先需要确认当前安装的Xmind8 Pro版本。可以在软件界面的左上角找到“Xmind8”菜单,点击下拉菜单中的“关于Xmind8”,弹出的窗口中会显示当前版本信息。请确保下载的序列号与当前版本匹配。 示例说明:如果当前安装的Xmind8版本为3.7.6,则需…

    other 2023年6月27日
    00
  • JavaScript中进制之间的转换

    JavaScript 中进制之间的转换 在JavaScript的开发中,我们经常需要进行进制之间的转换,例如将一个十六进制数转化为整型数,或者将一个十进制数转化为二进制字符串。本文将介绍在JavaScript中如何进行进制之间的转换。 二进制转其他进制 二进制转十进制 将一个二进制数转化为十进制数,可以使用parseInt函数,具体实现如下: const b…

    其他 2023年3月28日
    00
  • 在mac上安装office2016破解版

    在 Mac 上安装Office 2016破解版 Microsoft Office是一款非常常用的办公软件,但是它是商业软件,需要购买许可证。在 Mac 上安装Office 2016破解版可能会带来版权问题,因此我们不推荐这么做。但如果您真的非常需要,以下是一种可能的安装步骤。 步骤一:卸载官方版Office 在安装破解版之前,需要先卸载您当前已经安装的官方版…

    其他 2023年3月29日
    00
  • c、vdd、vss、vee和vpp的区别

    c、vdd、vss、vee和vpp的区别 在电子工程领域中,c、vdd、vss、vee和vpp分别是五个重要的概念,它们分别代表着电子电路中的不同元件或部件。在本文中,我们将简单介绍它们的区别。 C C是一个代表电容器的符号,用来表示电容器在电子电路中的位置。电容器是一种能够储存电荷的元件,它的主要作用是用来过滤电流或用来储存电能。在电路中,电容器通常用来消…

    其他 2023年3月28日
    00
  • Sybase:循环调用存储过程

    Sybase:循环调用存储过程的完整攻略 在Sybase中,存储过程是一种常用的操作数据的方式。有时候需要在存储过程中循环调用另一个存储过程,以实现一些特定的功能。本文将为您提供一份Sybase:循环调用存储过程的完整攻略,包括两个示例说明。 循环调用存储过程 在Sybase中,可以按照以下步骤循环调用存储过程: 创建存储过程:创建需要循环调用的存储过程。 …

    other 2023年5月5日
    00
合作推广
合作推广
分享本页
返回顶部