C# 如何使与GCC的弱链接工作?

更新时间:2024-02-08 下载TXT文档 下载Word文档

告诉GCC弱链接符号似乎有3种方法:

  • __attribute__((weak_import))
  • __attribute__((weak))
  • #pragma weak symbol_name

这些都不适合我:

#pragma weak asdf
extern void asdf(void) __attribute__((weak_import, weak));
...
{
    if(asdf != NULL) asdf();
}

我总是收到这样的链接错误:

Undefined symbols:
 "_asdf", referenced from:
      _asdf$non_lazy_ptr in ccFA05kN.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

我在OS X 10.5.5上使用GCC 4.0.1。 我究竟做错了什么?

  • int __attribute__((weak)) main() { ... }在gcc / Mac OS X上对我来说工作正常,但在gcc / MinGW上无法编译。 :(

我只是调查了一下,认为其他人可能会对我的发现感兴趣。

与weak_import的弱链接实际上仅适用于动态库。您可以使其与静态链接一起使用(如上面建议的那样通过指定-undefined dynamic_lookup),但这并不是一个好主意。这意味着直到运行时才会检测到未定义的符号。我个人会在生产代码中避免这种情况。

这是一个Mac OS X Terminal会话,显示如何使其工作:

这是f.c

int f(int n)
{
    return n * 7;
}

这是whatnof.c

#include <stdio.h>
#include <stdlib.h>

extern int f (int) __attribute__((weak_import));

int main() {
    if(f == NULL)
        printf("what, no f?\
");
    else
        printf("f(8) is %d\
", f(8));
    exit(0);
}

通过f.c创建动态库:

$ cc -dynamiclib -o f.dylib f.c

针对动态库进行编译和链接,列出动态库。

$ cc -o whatnof whatnof.c f.dylib
$ otool -L whatnof
whatnof:
       f.dylib (compatibility version 0.0.0, current version 0.0.0)
       /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0)

运行whatnof看看会发生什么:

$ whatnof
f(8) is 56

现在将f.dylib替换为空库(无符号):

$ mv f.dylib f.dylib.real
$ touch null.c
$ cc -dynamiclib -o f.dylib null.c

运行相同的whatnof看看会发生什么:

$ whatnof
what, no f?

weak_import的基本思想(或"用例")是,它使您可以链接到一组动态(共享)库,但随后可以对同一库的早期版本运行相同的代码。您可以针对NULL检查函数,以查看当前针对其运行代码的特定动态库是否支持它们。这似乎是Xcode支持的基本开发模型的一部分。我希望这个例子有用。它使我对Xcode设计的这一部分感到放心。

-Wl,-flat_namespace,-undefined,dynamic_lookup添加到用于执行最终链接的gcc编译器行。

  • 当我使用gcc / MinGW时,它说cc1.exe: error: unrecognized command line option"-flat_namespace,-undefined,dynamic_lookup"

您需要将MACOSX_DEPLOYMENT_TARGET变量设置为10.2或更高版本。请参阅Apple的文档及其有关弱链接的技术说明。

  • 我已经看过了,它就是这样设置的。 那不是我得到的错误。

最小的可运行Linux示例

main.c

#include <stdio.h>

int my_weak_var __attribute__((weak)) = 1;

int main(void) {
    printf("%d\
", my_weak_var);
}

notmain.c {短码网-DuanMa.NET}

int my_weak_var = 2;

编译并运行两个对象:

gcc -c -std=c99 -Wall -Wextra -pedantic -o main.o main.c
gcc -c -std=c99 -Wall -Wextra -pedantic -o notmain.o notmain.c
gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.o notmain.o
./main.out

输出:

2

不使用notmain.o进行编译和运行:

gcc -std=c99 -Wall -Wextra -pedantic -o main.out main.o
./main.out

输出:

1

GitHub上游。

因此,我们看到如果在notmain.o上给出,则非弱符号将按预期优先。

我们可以使用以下命令分析ELF目标文件符号:

nm main.o notmain.o

这使:

main.o:
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
0000000000000000 V my_weak_var
                 U printf

notmain.o:
0000000000000000 D my_weak_var

然后:

man nm

包含:

The symbol type. At least the following types are used; others are, as well, depending on the object file format. If lowercase, the symbol is usually local; if uppercase, the symbol is global (external). There are however a few lowercase symbols that are shown for special global symbols ("u","v" and"w").

"D"
"d" The symbol is in the initialized data section.

"V"
"v" The symbol is a weak object. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the weak symbol becomes zero with no error. On some systems, uppercase indicates that a default value has been specified.

但是,如果使用.a静态库,则可能必须使用-Wl,--whole-archive,如以下内容所述:如何在静态库中使gcc链接强符号覆盖弱符号?

弱符号也可以保持未定义状态,这在Binutils中导致"特定于平台的行为",请参见:未解决的弱函数的GCC行为

在Ubuntu 18.10,GCC 8.2.0上进行了测试。

从gcc doc手册中:

The weak attribute causes the declaration to be emitted as a weak
symbol rather than a global. This is primarily useful in defining
library functions which can be overridden in user code, though it
can also be used with non-function declarations. Weak symbols are
supported for ELF targets, and also for a.out targets when using
the GNU assembler and linker.

这意味着一个对象可以覆盖一个弱符号(在另一个对象/库中定义),而在链接时不会出错。目前尚不清楚是否要使用弱符号链接库。似乎您都尚未定义符号,并且库未正确链接。

  • 弱链接似乎有两种用法:gcc.gnu.org/ml/gcc/1999-02n/msg01219.html我试图链接到旧版本的库。 当前版本定义了旧版本没有的功能。 我希望能够在运行时使用新功能。
  • 该引用在这里不适用:" Mac OS X弱链接设计[来自经典的Mac OS代码片段管理器]。如果您熟悉[ELF],则可能会习惯于使用弱符号或 弱链接,弱符号可能会被非弱符号覆盖。等效的Mac OS X功能是弱定义-有关更多信息,请参见"符号定义的范围和处理"。
  • 同意:Apple文档不正确地描述了gcc。 公平考虑gcc首先并不能正确描述自己。

以上就是短码网小编为大家整理的《C# 如何使与GCC的弱链接工作?》相关内容,希望大家喜欢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若内容造成侵权/违法违规/事实不符,请将联系本站反馈,一经查实,立即处理!

C# 如何使与GCC的弱链接工作?》文档下载仅供参考学习,下载后请在24小时内删除。

转载注明出处:https://www.duanma.net/article/88c8ada6582.html

回到顶部