本文介绍了从C静态库中删除内部符号的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一些作为静态库发布的嵌入式代码。我们希望从库中删除所有内部符号,并仅使API符号可见。

下面是我们要做的一个示例:假设您有一个名为internal.c的文件和一个名为api.c的文件,如下所示:

/* internal.c */

int fibonacci(int n)
{
    /* Compute the nth Fibonacci number and return it */
}


/* api.c */

#include "internal.h"
#include <stdio.h>

void print_fibonacci(n)
{
    printf("Fibonacci(%d): %d
", n, fibonacci(n));
}

用户应该只能访问print_fibonacci函数,而所有内部符号(如fibonacci函数)都应该在发货前进行解析。这意味着用户应该能够定义他自己的名为fibonacci的函数,而不必担心与库冲突。

我们已经使用ld --relocatable尝试了内部链接,但似乎无法在之后使用objCopy删除符号。这真的可行吗?

谢谢你的帮助!

编辑:用户定义的fibonacci函数不应取代库定义的函数,它们应该能够共存。基本上,我正在寻找解决命名冲突的方法。

推荐答案

静态库本质上是一组目标文件。静态库中的所有目标文件都被视为由链接器单独提供。通常,不可能使链接器将某些符号视为内部符号,因为链接器没有足够的信息来执行此操作。

以下是解决这些问题的几个策略:

  • 为库中的非公共函数构造单独的名称空间。例如,您的fibonacci函数可以放在内部名称空间libfoo_internal_fibonacci中。如果您是独立,则可以在内部头文件中使用宏,如下所示:

    #define fibonacci INTERNAL_PREFIX ## fibonacci
    

    这将允许您在编译时任意更改前缀。我建议不要这样做,因为这会使调试变得更加困难。如果您可以处理更长的内部名称,这将是一个很好的策略。

    /li>
  • 使所有内部函数static合并翻译单元,使每个内部函数仅由一个翻译单元使用。这可能会解决您的问题,但它会使生成的程序变得更大:大多数链接器可以将对象作为一个整体进行处理,也可以根本不进行处理。如果您只想使用单个函数,则链接器必须包含巨大的目标文件,则程序中可能会出现大量死代码。

  • 将库转换为共享库,并使用映射文件或其他机制来指定应该导出哪些符号。在我看来,这是最好的选择,但它不是完全可移植的,也许您真的希望您的库保持静态。

这篇关于从C静态库中删除内部符号的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-28 15:07