动态加载与插件机制
更新时间:2026-10-01。配合 11-function-pointer-advanced,运行时扩展能力靠 dlopen + 函数表实现。
一、基本流程
c
void *h = dlopen("./plug.so", RTLD_NOW);
if (!h) { fprintf(stderr, "%s\n", dlerror()); ... }
plugin_init_fn init = (plugin_init_fn)dlsym(h, "plugin_init");取符号后经约定的函数指针/结构体调用;用完 dlclose,确保插件内资源(线程/内存/回调)已注销。
二、ABI 设计
主程序与插件只通过稳定的 C 接口(结构体含版本/大小字段)通信,避免跨编译器/版本的 name mangling 和布局问题;插件返回的内存要约定由谁释放。

三、常见坑
- 忘 -ldl / 未导出符号。
- 卸载后仍调用插件函数。
- 插件与主程序各自分配/释放内存。
小结
总结
用 dlopen(RTLD_NOW/LAZY 决定立即还是延迟绑定)打开共享库、dlsym 按约定名取出符号、dlerror 判错、dlclose 卸载,就能在运行时把 .so 变成插件;工程关键是主程序与插件只通过稳定的 C ABI(带版本号/大小字段的结构体或函数指针表)通信,以避开跨编译器 name mangling 和布局差异,并明确插件返回内存由谁释放、卸载前先注销线程/回调等资源——编译主程序需 -rdynamic、链接 -ldl,切忌卸载后仍调用其符号。