当出现符号时,为什么会看到符号链接错误消息?

时间:2019-03-19 16:36:41

标签: dll

我有两个目标文件,其中一个定义了几个符号,而其中一个未定义:

nm ./src/freertos/freertos.o |grep pvPortMalloc
000000000000d045 T pvPortMalloc

...和...

nm ./src/clib/new_delete.o
                 U _GLOBAL_OFFSET_TABLE_
                 U _Z12pvPortMalloci
                 U _Z9vPortFreePv
0000000000000019 T _ZdlPv
0000000000000000 T _Znwm

当我尝试将它们链接在一起时,会看到以下内容:

ld ./src/clib/new_delete.o ./src/freertos/freertos.o 
ld: warning: cannot find entry symbol _start; defaulting to 0000000000401000
ld: ./src/clib/new_delete.o: in function `operator new(unsigned long)':
new_delete.cc:(.text+0x13): undefined reference to `pvPortMalloc(int)'
ld: ./src/clib/new_delete.o: in function `operator delete(void*)':
new_delete.cc:(.text+0x2d): undefined reference to `vPortFree(void*)'

有人有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您的nm列表未显示./src/clib/new_delete.o中报告了任何未定义的符号 在./src/freertos/freertos.o中定义。

两者之间有相似之处 pvPortMalloc中定义的符号./src/freertos/freertos.o和未定义 我猜_Z12pvPortMalloci中的符号./src/clib/new_delete.o会导致您认为它们是 相同,但是链接器不会基于缺少同一性的任何相似性将符号等价。

符号_Z12pvPortMalloci是以下语言的C ++ mangled name

$ c++filt _Z12pvPortMalloci
pvPortMalloc(int)

显示./src/clib/new_delete.o是使用C ++编译器编译的。 ./src/freertos/freertos.o, 另一方面,是使用C编译器进行编译的,该编译器不进行名称修饰。

如果您想告诉C ++编译器外部名称pvPortMalloc在 您的源代码要使用C链接语言,因此不要乱用它, 您必须声明为extern "C"

错误

$ cat wrong.cpp
extern void * pvPortMalloc(int);

int main()
{
    return pvPortMalloc(42) != nullptr;
}

$ g++ -Wall -c wrong.cpp
$ nm wrong.o
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U _Z12pvPortMalloci

$ cat right.cpp 

extern "C" {
    void * pvPortMalloc(int);
    // And any more...
}

int main()
{
    return pvPortMalloc(42) != nullptr;
}

$ g++ -Wall -c right.cpp
$ nm right.o
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pvPortMalloc