Gcc 如何动态导出C函数

Gcc 如何动态导出C函数,gcc,linker,dynamic-linking,Gcc,Linker,Dynamic Linking,我的应用程序使用具有扩展API的静态库。API能够从外部共享库或“本地”二进制文件调用扩展init函数。也就是说,我可以在主可执行二进制文件中静态地包含扩展init函数 本地函数由dlsymcall搜索,初始化函数应从主二进制文件动态导出。这是下面的nm调用: nm -CD <binary> 此函数不是直接调用的-它只应通过dlsymcall加载 所以我有两个相关的问题: 如何强制链接器不从生成的二进制文件中排除此函数 如何强制编译器/链接器动态导出此函数 (我使用gcc编译并链接

我的应用程序使用具有扩展API的静态库。API能够从外部共享库或“本地”二进制文件调用扩展init函数。也就是说,我可以在主可执行二进制文件中静态地包含扩展init函数

本地函数由
dlsym
call搜索,初始化函数应从主二进制文件动态导出。这是下面的
nm
调用:

nm -CD <binary>
此函数不是直接调用的-它只应通过
dlsym
call加载

所以我有两个相关的问题:

  • 如何强制链接器不从生成的二进制文件中排除此函数
  • 如何强制编译器/链接器动态导出此函数

  • (我使用
    gcc
    编译并链接我的程序)

    不幸的是,GNU工具链的默认行为是默认情况下不从可执行文件导出符号(与默认导出所有符号的共享库相反)。您可以使用一个大锤
    -rdynamic
    标志,它告诉链接器从您的可执行文件导出所有符号。一个不那么麻烦的解决方案是在链接时通过
    -Wl,--dynamic list
    提供显式导出文件(参见中的示例用法)。

    不幸的是,GNU工具链的默认行为是默认情况下不从可执行文件导出符号(与默认导出所有符号的共享库相反)。您可以使用一个大锤
    -rdynamic
    标志,它告诉链接器从您的可执行文件导出所有符号。一个不那么麻烦的解决方案是在链接时通过
    -Wl,--dynamic list
    提供显式导出文件(参见中的示例用法)。

    好的,我将根据前面的评论发布一个答案

    要动态导出所有函数:
    -rdynamic

    要始终链接单个函数(即使未引用),您需要将
    -u
    添加到链接行


    要链接所有功能(即使未引用),请使用
    --整个归档文件
    。要返回正常链接,请使用
    ——无整个存档

    好的,我将根据前面的评论发布一个答案

    要动态导出所有函数:
    -rdynamic

    要始终链接单个函数(即使未引用),您需要将
    -u
    添加到链接行


    要链接所有功能(即使未引用),请使用
    --整个归档文件
    。要返回正常链接,请使用
    ——无需整个存档

    谢谢您提供的信息。现在我使用
    -rdynamic
    。不幸的是,为了避免删除elinker的init函数,我需要在代码中显式引用它。类似这样:
    void*unused=&extension\u init;(无效)(未使用)
    如果有更好的方法就太好了。@igor.sol您是否从静态库链接
    extension\u init
    ?在这种情况下,如果没有引用,链接器将不会链接对象文件,除非将
    -lxyz
    -Wl、-start-group
    -Wl、-end-group
    @yugr-rounding
    -lxyz
    环绕在
    -{start,end}-group
    之间,否则不会影响对象是否被拉入链接。您需要的是
    --整个存档
    --没有整个存档
    。对于单个函数,更简单的解决方案是将
    -uextension\u init
    添加到链接行。@EmployedRussian谢谢,修复了。你能给我们最后的建议一个答案吗?谢谢你提供的信息。现在我使用
    -rdynamic
    。不幸的是,为了避免删除elinker的init函数,我需要在代码中显式引用它。类似这样:
    void*unused=&extension\u init;(无效)(未使用)
    如果有更好的方法就太好了。@igor.sol您是否从静态库链接
    extension\u init
    ?在这种情况下,如果没有引用,链接器将不会链接对象文件,除非将
    -lxyz
    -Wl、-start-group
    -Wl、-end-group
    @yugr-rounding
    -lxyz
    环绕在
    -{start,end}-group
    之间,否则不会影响对象是否被拉入链接。您需要的是
    --整个存档
    --没有整个存档
    。对于单个函数,更简单的解决方案是将
    -uextension\u init
    添加到链接行。@EmployedRussian谢谢,修复了。你能给我们最后一个建议一个答案吗?这样我们就可以+1了?
    int init_func(INIT_STRUCT *);