0

0

C++怎么调用动态库 C++动态库调用的步骤与注意事项

冰火之心

冰火之心

发布时间:2025-07-20 12:44:01

|

999人浏览过

|

来源于php中文网

原创

c++++调用动态库的步骤包括创建动态库、加载动态库和调用其中的函数。1. 创建动态库时,linux使用g++生成.so文件,windows使用visual studio生成.dll文件,并使用extern "c"避免c++名字修饰;2. 加载动态库分为隐式链接和显式链接,前者在编译时指定库路径,后者使用dlopen/dlsym/dlclose(linux)或loadlibrary/getprocaddress/freelibrary(windows)实现;3. 注意事项包括确保abi兼容性、正确处理内存管理、避免跨模块释放内存、防止异常跨越动态库边界传播;4. 动态库更新后无需重新编译主程序,只要接口未变,替换库文件并重启程序即可生效;5. 解决依赖问题可通过设置环境变量ld_library_path(linux)或path(windows)、复制依赖库至系统目录、使用rpath指定搜索路径等方式实现;6. 动态库与静态库的主要区别在于链接方式、体积大小、更新机制及依赖管理,选择应根据实际需求权衡。

C++怎么调用动态库 C++动态库调用的步骤与注意事项

C++调用动态库,简单来说,就是让你的程序在运行时去加载并使用已经编译好的、独立于你的主程序的代码。这可以有效减少程序体积,方便代码更新和重用。

C++怎么调用动态库 C++动态库调用的步骤与注意事项

C++动态库调用的步骤与注意事项

C++怎么调用动态库 C++动态库调用的步骤与注意事项

动态库调用,说白了,就是搭桥。你得先找到桥,然后才能过河。

立即学习C++免费学习笔记(深入)”;

  1. 动态库的创建

    C++怎么调用动态库 C++动态库调用的步骤与注意事项

    先得有个桥吧?在Linux下,通常用g++编译生成.so文件,Windows下则是.dll文件。例如:

    // mylib.h
    #ifndef MYLIB_H
    #define MYLIB_H
    
    extern "C" { // 关键:使用extern "C"避免C++的名字修饰
    int add(int a, int b);
    }
    
    #endif
    // mylib.cpp
    #include "mylib.h"
    
    int add(int a, int b) {
    return a + b;
    }

    编译命令(Linux):

    g++ -fPIC -shared mylib.cpp -o libmylib.so

    这里-fPIC表示生成位置无关代码,-shared表示生成共享库。 Windows下,Visual Studio创建DLL项目即可。

  2. 动态库的加载

    有了桥,怎么用?有两种方式:隐式链接和显式链接。

    • 隐式链接:在编译时指定动态库。编译器会把动态库的信息写入可执行文件,运行时操作系统会自动加载。需要在编译时链接动态库,例如(Linux):

      g++ main.cpp -L. -lmylib -o main

      -L.表示在当前目录查找库,-lmylib表示链接名为libmylib.so的库。 Windows下,需要在项目设置中添加依赖库。

    • 显式链接:使用dlopendlsymdlclose等函数(Linux)或者LoadLibraryGetProcAddressFreeLibrary等函数(Windows)手动加载和卸载动态库。这种方式更加灵活,可以在运行时决定加载哪个库。

      // main.cpp
      #include 
      #include  // Linux下
      //#include  // Windows下
      
      int main() {
      void *handle = dlopen("./libmylib.so", RTLD_LAZY); // Linux
      //HMODULE handle = LoadLibrary("mylib.dll"); // Windows
      
      if (!handle) {
      std::cerr << "Cannot open library: " << dlerror() << std::endl;
      return 1;
      }
      
      typedef int (*add_func)(int, int); // 定义函数指针类型
      add_func add = (add_func)dlsym(handle, "add"); // Linux
      //add_func add = (add_func)GetProcAddress(handle, "add"); // Windows
      
      if (!add) {
      std::cerr << "Cannot find symbol add: " << dlerror() << std::endl;
      dlclose(handle); // Linux
      //FreeLibrary(handle); // Windows
      return 1;
      }
      
      int result = add(5, 3);
      std::cout << "Result: " << result << std::endl;
      
      dlclose(handle); // Linux
      //FreeLibrary(handle); // Windows
      return 0;
      }

      编译命令(Linux):

      g++ main.cpp -ldl -o main

      -ldl表示链接动态链接库。

  3. 注意事项

    飞笔AI
    飞笔AI

    飞笔AI致力于创作高质量的海报等图像,满足用户个性化设计需求。用户可通过平台便捷地创建各种风格和主题的海报、新媒体素材图等。

    下载
    • ABI兼容性:C++的ABI(应用程序二进制接口)在不同编译器和平台之间可能不兼容。这意味着用一个编译器编译的动态库可能无法被另一个编译器编译的程序加载。尽量使用相同的编译器和编译选项。

    • 名字修饰:C++编译器会对函数名进行名字修饰(name mangling),以支持函数重载。使用extern "C"可以避免C++的名字修饰,使得C程序或者其他语言可以调用C++的函数。

    • 依赖关系:动态库可能依赖于其他动态库。确保所有依赖的动态库都位于正确的路径下,或者通过设置环境变量(如LD_LIBRARY_PATH在Linux下)来指定动态库的搜索路径。 Windows下,可以将DLL放在可执行文件同一目录下,或者添加到系统PATH环境变量中。

    • 内存管理:动态库和主程序之间的内存管理需要特别小心。避免在动态库中分配内存,然后在主程序中释放,反之亦然。最好由同一模块负责分配和释放内存。

    • 异常处理:跨越动态库边界抛出异常可能会导致未定义的行为。尽量避免在动态库中抛出异常,或者确保主程序和动态库使用相同的异常处理机制。

动态库的调用,就像拼积木,拼对了就能搭出漂亮的房子,拼错了就可能摇摇欲坠。

动态库更新后如何不重新编译主程序?

这是动态库的优势之一。如果你只是修改了动态库的实现,而接口(函数签名)没有改变,那么你只需要替换掉旧的动态库文件即可,无需重新编译主程序。但如果接口发生了变化,那就必须重新编译主程序了。

具体操作:

  1. 修改动态库代码,重新编译生成新的动态库文件。
  2. 用新的动态库文件替换旧的动态库文件。确保新的动态库文件位于主程序可以找到的路径下(例如,与主程序在同一目录下,或者在环境变量指定的路径下)。
  3. 重启主程序。主程序会加载新的动态库。

如何解决动态库依赖问题?

动态库依赖问题是常见的问题。如果你的动态库依赖于其他动态库,而这些依赖的动态库又不在系统默认的搜索路径下,那么主程序在加载你的动态库时就会失败。

解决方法

  1. 设置环境变量:在Linux下,可以设置LD_LIBRARY_PATH环境变量,将依赖的动态库所在的目录添加到搜索路径中。在Windows下,可以将依赖的DLL添加到系统PATH环境变量中。

    export LD_LIBRARY_PATH=/path/to/dependency:$LD_LIBRARY_PATH
  2. 将依赖的动态库复制到系统目录:将依赖的动态库复制到系统默认的动态库搜索路径下(例如,/usr/lib/usr/local/lib在Linux下,C:\Windows\System32在Windows下)。但这通常需要管理员权限,并且可能会影响其他程序。

  3. 使用rpath(Linux):在编译时,可以使用-Wl,-rpath选项指定动态库的搜索路径。这样,在运行时,动态链接器会优先在指定的路径下搜索动态库。

    g++ main.cpp -L. -lmylib -Wl,-rpath=. -o main

    这表示在当前目录搜索动态库。

  4. 使用绝对路径:在显式链接时,可以使用动态库的绝对路径。但这会降低程序的灵活性。

动态库与静态库的区别是什么?

  • 链接方式:静态库在编译时被链接到可执行文件中,成为可执行文件的一部分。动态库在运行时才被加载到内存中。
  • 体积:使用静态库会增加可执行文件的体积。使用动态库可以减少可执行文件的体积,因为多个程序可以共享同一个动态库。
  • 更新:静态库更新后,需要重新编译所有使用它的程序。动态库更新后,只需要替换动态库文件即可,无需重新编译主程序(前提是接口没有改变)。
  • 依赖:静态库不存在依赖问题,因为代码已经包含在可执行文件中。动态库存在依赖问题,需要确保所有依赖的动态库都可用。

选择静态库还是动态库,取决于你的需求。如果你的程序需要独立运行,不需要依赖其他库,或者你希望避免动态库的依赖问题,那么可以选择静态库。如果你的程序需要频繁更新,或者你希望减少程序体积,那么可以选择动态库。

相关专题

更多
硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1049

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

86

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

456

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

11

2026.01.19

windows查看端口占用情况
windows查看端口占用情况

Windows端口可以认为是计算机与外界通讯交流的出入口。逻辑意义上的端口一般是指TCP/IP协议中的端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等等。怎么查看windows端口占用情况呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

641

2023.07.26

查看端口占用情况windows
查看端口占用情况windows

端口占用是指与端口关联的软件占用端口而使得其他应用程序无法使用这些端口,端口占用问题是计算机系统编程领域的一个常见问题,端口占用的根本原因可能是操作系统的一些错误,服务器也可能会出现端口占用问题。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1124

2023.07.27

windows照片无法显示
windows照片无法显示

当我们尝试打开一张图片时,可能会出现一个错误提示,提示说"Windows照片查看器无法显示此图片,因为计算机上的可用内存不足",本专题为大家提供windows照片无法显示相关的文章,帮助大家解决该问题。

796

2023.08.01

windows查看端口被占用的情况
windows查看端口被占用的情况

windows查看端口被占用的情况的方法:1、使用Windows自带的资源监视器;2、使用命令提示符查看端口信息;3、使用任务管理器查看占用端口的进程。本专题为大家提供windows查看端口被占用的情况的相关的文章、下载、课程内容,供大家免费下载体验。

452

2023.08.02

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

16

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 7.3万人学习

C 教程
C 教程

共75课时 | 4.2万人学习

C++教程
C++教程

共115课时 | 13.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号