参考: - https://stackoverflow.com/questions/36873742/calling-a-shared-library-from-c Calling a shared library from c++ - https://stackoverflow.com/questions/8806630/c-implementation-of-a-class-methods-in-a-separated-shared-library C++: implementation of a class methods in a separated shared library - https://www.cnblogs.com/zongzi10010/p/16415920.html dlopen重复打开的一些问题 - https://blog.csdn.net/chgw_/article/details/121005049 静态库与动态库 - https://stackoverflow.com/questions/36384195/how-to-correctly-assign-a-pointer-returned-by-dlsym-into-a-variable-of-function How to correctly assign a pointer returned by dlsym into a variable of function pointer type?
1. linux下对动态库的操作
使用 dlopen()
,dlsym()
,dlerror()
,dlclose()
这四个函数,在程序内完成动态库的加载,查找函数,卸载功能,使用时需要调用头文件 #include<dlfcn.h>
2. 多次加载同一个 libso 库
同一个动态库文件可能被使用多次,但只加载一次。
因此,每个动态库文件都配置一个初始值为 0 的计数器,当调用 dlopen() 函数加载它时,计数器加 1,当有 dlclose() 函数卸载它时,计数器减 1。只有当计数器减至 0 时,动态库才会被真正地卸载掉,指向链接库的指针也会失效。
3. CMake 编译 so 库
ADD_LIBRARY (soprinter SHARED soprinter.cc)
TARGET_LINK_LIBRARIES (soprinter libxxx.so)
结果会生成 libsoprinter.so
文件
4. 使用 dlopen
#include <cstdio>
extern "C" void hello( const char* text ) {
printf("Hello, %s\n", text);
}
#include <dlfcn.h>
extern "C" typedef void (*hello_t)( const char* text );
int main() {
void* lib = dlopen("./libhello.so", RTLD_LAZY);
hello_t hello = (hello_t)dlsym( lib, "hello" );
hello("World!");
dlclose(lib);
}
5. 更抽象的使用方式
In the library
struct export_vtable {
void (*helloworld)(void);
};
struct export_vtable exports = { func };
In the caller
struct export_vtable {
void (*helloworld)(void);
};
int main() {
struct export_vtable* imports;
void *handle = dlopen("./foo.so", RTLD_NOW);
if (handle) {
imports = dlsym(handle, "exports");
if (imports) imports->helloworld();
}
return 0;
}