link 处使用 extern 关键字的未定义引用错误
Undefined reference error at link using extern keyword
我在两个库 libA.a(静态)和 libB.so(动态)之间的 link 处遇到问题,这些库是从 C 源代码创建的。
在其中一个用于生成libB.so的源文件中,我有以下功能:
static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size) { ... }
static void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { ... }
当我 运行 nm libB.so | grep unassigned_mem
我有:
00000000004662a7 t unassigned_mem_read
0000000000466337 t unassigned_mem_write
在用于制作 libA.a 的源文件中,我有:
extern uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size);
extern void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size);
进一步调用这些方法。
我编译的时候,一切正常。但是在 link,我有:
[build] qmg-mmio.c:47: undefined reference to 'unassigned_mem_read'
[build] qmg-mmio.c:84: undefined reference to 'unassigned_mem_write'
当我这样做时 nm libA.a | grep unassigned_mem
我有:
U unassigned_mem_read
U unassigned_mem_write
我link顺序是:libB.so,libA.a.
符号相同,怎么会解析不出来呢?
此外,当我将所有源代码编译在一起时,link 就没有问题了。 link我想念一个静态库和一个动态库时是否有微妙之处?
对于文件范围标识符,static
关键字指定内部链接。这意味着标识符和任何关联的定义对于它们出现的翻译单元来说基本上是私有的。为了避免混淆,请注意这仅与 "static libraries" 外围相关,尤其是静态库中打算由库用户直接调用的函数必须 而不是 被声明为 static
,因为它直接且明确地阻止了此类调用。
链接是标识符的属性,在它们的范围内,而不是它们标识的对象或函数,并且在其他范围内不一定是相同的标识符。此外,同一标识符可以与不同范围内的不同对象和/或函数相关联。特别是,给定标识符的 extern
al 声明与不同的函数或对象关联,而不是与相同标识符的任何内部声明关联的函数或对象,因此您不能将出现在一个范围内的内部声明重新定义为外部声明通过在其他范围内添加声明。
鉴于你似乎不愿意修改包含你要调用的函数的库,我假设它是由第三方提供的。在那种情况下,您应该了解声明这些函数 static
的部分目的是为了让库用户 您 不要[=24] =] 直接打电话给他们。它们不是库外部接口的一部分。
我在两个库 libA.a(静态)和 libB.so(动态)之间的 link 处遇到问题,这些库是从 C 源代码创建的。
在其中一个用于生成libB.so的源文件中,我有以下功能:
static uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size) { ... }
static void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { ... }
当我 运行 nm libB.so | grep unassigned_mem
我有:
00000000004662a7 t unassigned_mem_read
0000000000466337 t unassigned_mem_write
在用于制作 libA.a 的源文件中,我有:
extern uint64_t unassigned_mem_read(void *opaque, hwaddr addr, unsigned size);
extern void unassigned_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size);
进一步调用这些方法。
我编译的时候,一切正常。但是在 link,我有:
[build] qmg-mmio.c:47: undefined reference to 'unassigned_mem_read'
[build] qmg-mmio.c:84: undefined reference to 'unassigned_mem_write'
当我这样做时 nm libA.a | grep unassigned_mem
我有:
U unassigned_mem_read
U unassigned_mem_write
我link顺序是:libB.so,libA.a.
符号相同,怎么会解析不出来呢?
此外,当我将所有源代码编译在一起时,link 就没有问题了。 link我想念一个静态库和一个动态库时是否有微妙之处?
对于文件范围标识符,static
关键字指定内部链接。这意味着标识符和任何关联的定义对于它们出现的翻译单元来说基本上是私有的。为了避免混淆,请注意这仅与 "static libraries" 外围相关,尤其是静态库中打算由库用户直接调用的函数必须 而不是 被声明为 static
,因为它直接且明确地阻止了此类调用。
链接是标识符的属性,在它们的范围内,而不是它们标识的对象或函数,并且在其他范围内不一定是相同的标识符。此外,同一标识符可以与不同范围内的不同对象和/或函数相关联。特别是,给定标识符的 extern
al 声明与不同的函数或对象关联,而不是与相同标识符的任何内部声明关联的函数或对象,因此您不能将出现在一个范围内的内部声明重新定义为外部声明通过在其他范围内添加声明。
鉴于你似乎不愿意修改包含你要调用的函数的库,我假设它是由第三方提供的。在那种情况下,您应该了解声明这些函数 static
的部分目的是为了让库用户 您 不要[=24] =] 直接打电话给他们。它们不是库外部接口的一部分。