在 Linux 下用 C++ 使用动态库(.so),通常包含 编译动态库、使用动态库、以及 运行时加载(动态加载) 三种情况。下面系统地给你讲一遍。
// mylib.cpp
#include <iostream>
extern "C" void hello() {
std::cout << "Hello from dynamic lib!" << std::endl;
}
⚠️ 如果是 C++ 函数,建议用
extern "C",否则函数名会被 name mangling。
g++ -fPIC -shared mylib.cpp -o libmylib.so
参数说明:
-fPIC:生成位置无关代码(必须)-shared:生成共享库// main.cpp
extern "C" void hello();
int main() {
hello();
}
g++ main.cpp -L. -lmylib -o main
-L.:库路径-lmylib:链接 libmylib.soexport LD_LIBRARY_PATH=.
./main
或者把 .so 放到:
/usr/lib
/lib
适合 插件系统 / 热更新
// plugin.cpp
extern "C" void run() {
std::cout << "plugin run!" << std::endl;
}
g++ -fPIC -shared plugin.cpp -o libplugin.so
#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);
}
g++ main.cpp -ldl -o main
// 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;
ldd main
查看依赖
nm -D libxxx.so
extern "C"libxxx.so.1| 方式 | 特点 |
|---|---|
| 编译时链接 | 简单、常用 |
| dlopen | 灵活、插件化 |
| 抽象类接口 | 适合 C++ |
如果你有 具体场景(比如:CMake、Qt、ROS、插件系统),我可以给你更针对性的示例。