1、动态库可以调用主程序的符号
- 主程序的符号在全局符号表中
主程序编译链接后,全局符号默认暴露在符号表,供动态链接器查找。
- 动态库加载时会加载所有依赖的符号
当用 dlopen
加载动态库时,动态链接器会自动在主程序符号表中查找动态库需要的符号。
- 主程序和动态库共享同一个地址空间
动态库与主程序运行在同一进程内,因而可以直接访问对方的内存和符号。
2、主程序不能直接调用动态库的符号
- 动态库的符号默认不可见
编译动态库时,符号通常被隐藏,除非显式导出。 - 需要显式导出才能使用
主程序想调用动态库的函数,必须通过导出接口(如 __attribute__((visibility("default")))
或 Windows 的 __declspec(dllexport)
)保证符号可见。 - 可能存在 ABI 兼容性问题
动态库与主程序必须遵循相同的调用约定和数据类型规范,否则调用会失败。
3、实践建议
- 插件模式设计
让动态库调用主程序导出的接口(如单例工厂),动态库通过该接口注册自身,实现插件机制。 - 主程序调用动态库函数
使用 dlsym
动态查找动态库导出符号地址,避免符号不可见问题。 - 保证 ABI 兼容性
确保主程序和动态库的编译选项、调用约定、数据结构对齐一致。 - 使用
extern "C"
避免 C++ 名字修饰
导出接口采用 C 语言风格,避免因 C++ 名字修饰导致符号查找失败。