Open nonocast opened 2 years ago
使用一个dylib通常有2个方式,多数会采用编译时绑定,在做plugin的时候也会用到运行时链接。
在没有debug信息的时候,我们只能通过nm从dylib或so中获取symbols, 但无法获取完整的函数签名,所以如果在编译时就需要有header配合,在运行时就需要有对应的函数签名。
nm
➜ file libcalc.dylib libcalc.dylib: Mach-O 64-bit dynamically linked shared library arm64 ➜ size libcalc.dylib text data bss dec hex filename 104 0 0 104 68 libcalc.dylib ➜ gobjdump -x libcalc.dylib libcalc.dylib: file format mach-o-arm64 libcalc.dylib architecture: aarch64, flags 0x00000050: HAS_SYMS, DYNAMIC start address 0x0000000000000000 MACH-O header: magic: 0xfeedfacf cputype: 0x100000c (ARM64) cpusubtype: 0 (ARM64_ALL) filetype: 0x6 ncmds: 0xe sizeocmds: 0x298 flags: 0x100085 version: 2 Sections: Idx Name Size VMA LMA File off Algn 0 .text 00000020 0000000000003f98 0000000000003f98 00003f98 2**2 CONTENTS, ALLOC, LOAD, CODE 1 __TEXT.__unwind_info 00000048 0000000000003fb8 0000000000003fb8 00003fb8 2**2 CONTENTS, ALLOC, LOAD, READONLY, CODE SYMBOL TABLE: 0000000000003f98 g 0f SECT 01 0000 [.text] _add ➜ nm libcalc.dylib 0000000000003f98 T _add
然后我们就可以通过dlopen, dlsym, dlclose操作:
#include <dlfcn.h> #include <mach-o/dyld.h> #include <stdio.h> typedef int (*add_func_pointer)(int, int); int main(int args, char *argv[]) { char *calc_dylib_path = "./libcalc.dylib"; printf("%s\n", calc_dylib_path); void *module = dlopen(calc_dylib_path, RTLD_LAZY); if (module == NULL) { printf("open dylib failed. (code=%s)\n", dlerror()); } add_func_pointer add_func = dlsym(module, "add"); if (add_func) { int sum = add_func(2, 7); printf("2+7=%d\n", sum); } dlclose(module); return 0; }
obs的整个plugin体系就是通过dlopen来实现的。
使用一个dylib通常有2个方式,多数会采用编译时绑定,在做plugin的时候也会用到运行时链接。
在没有debug信息的时候,我们只能通过
nm
从dylib或so中获取symbols, 但无法获取完整的函数签名,所以如果在编译时就需要有header配合,在运行时就需要有对应的函数签名。然后我们就可以通过dlopen, dlsym, dlclose操作:
obs的整个plugin体系就是通过dlopen来实现的。
参考阅读