我有两个目标文件,其中一个定义了几个符号,而其中一个未定义:
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*)'
有人有什么想法吗?
答案 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