使用 dlopen 加载 lib so 库

创建日期: 2024-06-04 18:27 | 作者: 风波 | 浏览次数: 14 | 分类: C++

参考: - 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;
}
14 浏览
9 爬虫
0 评论