温馨提示×

linux c++配置怎样动态库

小樊
39
2026-09-14 06:24:10
栏目: 编程语言

在 Linux 下用 C++ 使用动态库(.so),通常包含 编译动态库使用动态库、以及 运行时加载(动态加载) 三种情况。下面系统地给你讲一遍。


一、编译生成动态库(.so)

1️⃣ 示例代码

// mylib.cpp
#include <iostream>

extern "C" void hello() {
    std::cout << "Hello from dynamic lib!" << std::endl;
}

⚠️ 如果是 C++ 函数,建议用 extern "C",否则函数名会被 name mangling。

2️⃣ 编译为动态库

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

参数说明:

  • -fPIC:生成位置无关代码(必须)
  • -shared:生成共享库

二、使用动态库(编译时链接)

1️⃣ 主程序

// main.cpp
extern "C" void hello();

int main() {
    hello();
}

2️⃣ 编译主程序

g++ main.cpp -L. -lmylib -o main
  • -L.:库路径
  • -lmylib:链接 libmylib.so

3️⃣ 运行程序

export LD_LIBRARY_PATH=.
./main

或者把 .so 放到:

/usr/lib
/lib

三、运行时动态加载(dlopen)

适合 插件系统 / 热更新

1️⃣ 动态库代码

// plugin.cpp
extern "C" void run() {
    std::cout << "plugin run!" << std::endl;
}
g++ -fPIC -shared plugin.cpp -o libplugin.so

2️⃣ 主程序(使用 dlopen)

#include <dlfcn.h>
#include <iostream>

int main() {
    void* handle = dlopen("./libplugin.so", RTLD_LAZY);
    if (!handle) {
        std::cerr << dlerror() << std::endl;
        return 1;
    }

    using Func = void(*)();
    Func run = (Func)dlsym(handle, "run");

    if (!run) {
        std::cerr << dlerror() << std::endl;
        return 1;
    }

    run();
    dlclose(handle);
}

3️⃣ 编译

g++ main.cpp -ldl -o main

四、C++ 类在动态库中(进阶)

动态库

// animal.h
class Animal {
public:
    virtual void speak() = 0;
    virtual ~Animal() {}
};

extern "C" Animal* create();
// animal.cpp
#include "animal.h"
#include <iostream>

class Dog : public Animal {
public:
    void speak() override {
        std::cout << "Wang!" << std::endl;
    }
};

extern "C" Animal* create() {
    return new Dog();
}

使用

Animal* a = create();
a->speak();
delete a;

五、常见问题

❓ 找不到 .so

ldd main

查看依赖

❓ 名字被 C++ 改了

nm -D libxxx.so

❓ 推荐做法

  • 插件用 extern "C"
  • 接口用抽象类
  • 版本控制:libxxx.so.1

六、总结

方式 特点
编译时链接 简单、常用
dlopen 灵活、插件化
抽象类接口 适合 C++

如果你有 具体场景(比如:CMake、Qt、ROS、插件系统),我可以给你更针对性的示例。

0