静态档案中的 C 符号可见性

2024-01-11

我有文件 foo.c bar.c 和 baz.c,以及定义函数 myfn() 的包装器代码 myfn.c,该函数使用其他文件中的代码和数据。

我想创建诸如目标文件或存档 myfn.o 或 libmyfn.a 之类的内容,以便 myfn() 可以供其他项目使用,而无需从 {foo,bar,baz}.o 导出大量符号以及。

在 Linux/gcc 中执行此操作的正确方法是什么?谢谢。


更新:我找到了一种方法。我本来应该强调这是关于静态档案,而不是 DSO。无论如何,食谱:

  1. #define PUBLIC __attribute__ ((visibility("default")))然后标记myfn() as PUBLIC in myfn.c。不要标记任何其他东西PUBLIC.

  2. 编译对象gcc -c foo.c bar.c baz.c myfn.c -fvisibility=hidden,这将所有内容标记为隐藏,除了myfn().

  3. 使用创建一个方便的存档ld的部分链接开关:ld -r foo.o bar.o baz.o myfn.o -o libmyfn.a

  4. 本地化所有未本地化的内容PUBLIC像这样:objcopy --localize-hidden libmyfn.a

  5. Now nm says myfn是唯一的全球符号libmyfn.a随后链接到其他程序效果很好:gcc -o main main.c -L. -lmyfn(这里,程序调用myfn();如果它试图打电话foo()那么编译就会失败)。

如果我使用ar代替ld -r在步骤 3 中,然后在步骤 5 中编译失败:我猜ar尚未链接foo etc to myfn,一旦这些功能本地化就不再可以了,而ld -r在链接被本地化之前解析该链接。

我欢迎任何确认这是“正确”方式的回应,或者描述实现相同目的的更巧妙的方式。


不幸的是,全局变量的 C 链接是全有或全无的,因为所有模块的全局变量都可以在libmyfn.a的外部符号的最终列表。

gcc工具链提供了一个扩展,可让您对外部用户隐藏符号,同时使它们可供库中的其他翻译单元使用:

foo.h:

void foo();

foo.c:

void foo() __attribute__ ((visibility ("hidden")));

myfn.h:

void myfn();

myfn.c:

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

void myfn() {
    printf("calling foo...\n");
    foo();
    printf("calling foo again...\n");
    foo();
}

为了可移植性,您可能会受益于为__attribute__ ((visibility ("hidden"))),并将其放置在条件编译块中gcc.

此外,Linux 还提供了实用程序称为strip http://www.thegeekstuff.com/2012/09/strip-command-examples/,它允许您从编译的目标文件中删除一些符号。选项-N and -K让您识别要保留或删除的各个符号。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

静态档案中的 C 符号可见性 的相关文章

随机推荐

  • 被动事件监听器

    function loadMenuBasedScript var getMenuDependentValues window addEventListener DOMContentLoaded function document getEl
  • 由于地理单位不同,我在向 ggmap 添加 shapefile 时遇到问题

    我正在尝试将 ESRI shapefile shp 添加到北卡罗来纳州的 ggmap 图中 其中包含以下代码 x lt get map location North Carolina zoom 6 maptype terrain ggmap
  • 将opencv帧写入gstreamer rtsp服务器管道

    我正在尝试将 opencv 图像放入 python 中的 gstreamer rtsp 服务器中 我在 mediafactory 中写作时遇到一些问题 我是 gst rtsp server 的新手 而且文档很少 所以我不确定我是否使用了正确
  • gnuplot 中的水平直方图

    我正在尝试在 gnuplot 中绘制水平直方图 这是我当前的垂直 通常类型 直方图 width 0 5 hist x width width floor x width width 2 0 set boxwidth width 0 9 se
  • GitHub for Windows 的“同步”有什么作用?

    使用适用于 Windows 的 GitHub 您可以 发布 分支 然后将该分支 同步 到 GitHub 同步基本上是git pull and git push 或者还有更多的事情吗 如果我想从命令行执行与 sync 完全相同的步骤 我应该做
  • NSTableView 内 NSTextFieldCell 中的可点击 url 链接?

    我有一个在 NSTextFieldCell 中使用的 NSAttributedString 它创建了几个可点击的 url 链接 并将一个大的 NSAttributedString 放入 NSTextFieldCell 中 每当我正常查看 N
  • 如何向 Django Celery Flower Monitoring 添加身份验证和端点?

    我一直在本地使用flower 它似乎很容易设置和运行 但我不知道如何在生产环境中设置它 特别是 如何添加身份验证以及如何定义 url 来访问它 对于自定义地址 请使用 address旗帜 对于身份验证 请使用 basic auth flag
  • 如何以编程方式将 Word 文件转换为 PDF? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我发现了几个开源 免费软件程序 允许您将 doc 文件转换为 pdf 文件 但它们都是应用程序 打印机驱
  • 更改颜色文本谷歌甘特图(javascript),无需CSS

    如何在不使用或插入 css 的情况下更改左侧文本颜色 此代码与文档相同 我知道颜色取决于资源 我不会更改活动栏的颜色 而只会更改与其关联的文本 google charts load current packages gantt google
  • 如何在 Python 中绘制第一个楔形在顶部的饼图? [matplotlib]

    如何使用 Matplotlib 绘制第一个楔形从中午开始 即在饼图顶部 的饼图 默认值是用于pyplot pie 将第一个边缘放置在三点钟位置 如果能够自定义它就太好了 仅仅因为这出现在我的 Google 搜索中 我会补充说 与此同时 ma
  • ASP.Net 5 登录类库

    我对依赖注入有点陌生 我正在尝试开始使用 ASP NET 5 并且正在努力弄清楚如何使用 ASP NET 5 类库中的服务 尤其是像日志记录和 EF 数据访问这样简单的事情 例如 我已按照此处的指南进行操作 http docs asp ne
  • 避免向列表中添加重复元素 C#

    string lines3 new string 100 List
  • 为什么我在 Ubuntu 中使用 wget 无法获取此页面? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 http 121 199 111 177 http 121 199 111 177 我用win7 IE8 访问这个网址 没问题 可以获取页面 但如果我
  • Spring 3.1 JSON 日期格式

    我正在使用带注释的 Spring 3 1 MVC 代码 spring mvc 当我通过 RequestBody 发送日期对象时 日期显示为数字 这是我的控制器 Controller RequestMapping test public cl
  • Visual Studio Code 文件。排除设置不起作用

    我正在使用 Unity 并尝试从文件资源管理器侧边栏中排除 meta 文件 我导航到文件 gt 首选项 gt 用户设置 或工作区设置 无关紧要 并将文件的内容设置为以下内容 Place your settings in this file
  • TestCafe - 将选择器的结果存储在变量中

    因此 为了测试 我的搜索结果根据我输入的关键字而有所不同 我想在输入关键字之前存储 searchResults 的节点列表 然后将它们与添加关键字后获得的 searchResults 的节点列表进行比较 但是我无法让它工作 我试过了 let
  • Google Chrome 开发者工具包速度很慢

    我已经使用 Google Chrome 的开发工具包 元素检查 堆栈跟踪 JavaScript 调试等 一段时间了 并取得了巨大的成功 然而 大约两周前 它突然变得非常迟缓 例如 当我右键单击 UI 中的某个元素 然后单击 检查元素 时 或
  • Onedrive cors 在 JavaScript 中下载

    我正在尝试在客户端 JavaScript 中处理 onedrive 文件 但首先我需要一种使用 XMLHttpRequest 下载文件的方法 Onedrive支持cors进行很多操作 但是将文件下载到javascript中存在以下问题 正如
  • 在mysql中创建表约束

    我有一个表 其中有一些列a b c每列都有另一列 例如 x y z 这取决于a b c分别 x y z将会有价值1 if a b c具有任何值并且将包含 null 如果a b c has null 举个例子吧 存储的值a is 2 and
  • 静态档案中的 C 符号可见性

    我有文件 foo c bar c 和 baz c 以及定义函数 myfn 的包装器代码 myfn c 该函数使用其他文件中的代码和数据 我想创建诸如目标文件或存档 myfn o 或 libmyfn a 之类的内容 以便 myfn 可以供其他