c++ - 在 OS X 上链接期间包装符号

标签 c++ macos gcc shared-libraries ld

我试图在链接期间用一个符号换行。据我所知,这很容易用 ld --wrap 选项完成,但在 OS X 上它不可用。有'-idefinition:indirection',在这里我试图欺骗 main 以便它打印 42:

a.cpp:

int foo() {
    return 1;
}

b.cpp:

int wrap_foo() {
    return 42;
}

主要.cpp:

#include <cstdio>

int foo();
int wrap_foo();

int main() {
    printf("%d\n", foo());
}

我如何构建和链接它们:

$ gcc -c *.cpp
$ gcc -Wl,-i__Z3foov:__Z8wrap_foov *.o
duplicate symbol __Z3foov in:
    a.o
    b.o
ld: 1 duplicate symbol for architecture x86_64

是否有可能实现我想要的?


编辑: 在我的任务中,我无法控制 a.cpp 和 main.cpp(只有它们的对象),但我可以编写任何代码并在链接之前对对象执行任何我需要的操作。

我发现了以下与类似任务相关的问题(并更好地描述了它) GNU gcc/ld - wrapping a call to symbol with caller and callee defined in the same object file 重读答案,我发现情况相同,符号已经存在,我将发生碰撞。

如何在不触及源代码的情况下从 a.o 中删除 foo?

最佳答案

这是否必须在链接而不是运行时完成?请注意完全确定您要做什么,所以只问。

使用该链接器命令的问题在于它会创建一个新符号,这就是您得到重复符号的原因。

-alias symbol_name alternate_symbol_name
                 Create an alias named alternate_symbol_name for the symbol
                 symbol_name.  By default the alias symbol has global visibil-
                 ity.  This option was previous the -idef:indir option.

如果您没有定义 foo 的 a.cpp(即您省略了 foo),您可以这样做:

tmp$ gcc -Wl,-alias,__Z8wrap_foov,__Z3foov b.o main.o
tmp$ ./a.out
42

你总是可以做的是让 a.cpp 有另一个 foo,比如 original_foo。这样,如果您想要该实现,您可以使用别名将其映射到 foo。不完美,但它会大致达到你想要的。您已经在链接处完成了调整它的工作,因此它看起来可能是可以接受的。

关于c++ - 在 OS X 上链接期间包装符号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39441587/

相关文章:

c++ - 算法中令人费解的行为应该根据列表的项目创建 4 个列表

java - 在 macOS 上安装 Eclipse

gcc - 为什么 gcc 不从命令行传递宏值?

c - 为什么只有注释更改的两个二进制程序在 gcc 中不完全匹配?

c - GCC 编译器错误

c++ Windows API递归搜索未返回预期目录

c++ - 为什么当我取消引用数组指针时,结果值是指向数组第一个元素的指针,而不是整个数组对象?

android - 如何在 C/Android NDK 中将字符串日期转换为毫秒

c - 为什么 strptime() 在 OSX 和 Linux 上表现不同?

macos - 如何在 Vim for MacOS 中初始化 sparkup 插件?