Bootstrap

在动态库中如何调用外部函数?

方法一:导出全部符号表

在编译主程序时,添加-rdynamic编译选项:

$ gcc -m32 -rdynamic -o main main.c -ldl

或者这样:

gcc -m32 -Wl,--export-dynamic -o main main.c -ldl

这样编译出来的可执行程序main中的符号表会被全部导出,调用的动态库才能直接使用main中的func_in_main方法。

方法二:导出指定符号表

定义一个文件,只导出需要的符号列表,比如exported.txt文件:

{
    extern "C"
    {
        func_in_main;
    };
};

在编译主程序时,指定此文件即可:

gcc -m32 -Wl,-dynamic-list=./exported.txt -o main main.c -ldl

这样编译出来的可执行程序main中被导出的符号,就可以在动态库中直接使用了。

方法三:回调函数注册

在动态库中定义一个默认实现:

// 默认实现
void func_in_main_def(void)
{
    printf("the main is lazy, do NOT register me! \n");
}
// 定义外部函数指针
void (*func_in_main)() = func_in_main_def;

并提供一个函数注册的方法:

void register_func(void (*pf)())
{
    func_in_main = pf;
}

这样应用程序main的开发者,就可以按照自己的需求来决定如何使用动态库了,相对更加灵活。

使用总结

  1. 如果是插件框架的构建者,应用程序是固定的,功能开发者按照插件框架去实现功能,更适合采用符号表导出的方式;
  2. 如果是功能的实现者,功能插件库是固定的,则更适合采用回调函数注册的方法。

扩展链接

https://blog.csdn.net/qq_26105397/article/details/117928294
https://cloud.tencent.com/developer/article/1837804?from=15425

;