0

现在我正在尝试使用 arm-none-eabi 工具链将 Nuttx 与 libc++ 交叉编译。大多数事情都很好,但是一些 C++ 应用程序有一个未定义的std::nothrow. 我发现这std::nothrow似乎是libsupc++.a在工具链中定义的:

new_handler.o:
00000000 b (anonymous namespace)::__new_handler
00000000 T std::get_new_handler()
00000000 T std::set_new_handler(void (*)())
00000000 R std::nothrow

我确保libsupc++.a链接到我的应用程序。我的应用参考std::nothrow如下:

U nothrow

我猜未定义的引用是由于这些名称不匹配而发生的,一个有命名空间,另一个没有命名空间。如何解决此命名空间不匹配问题?

以下是我的链接命令行:

arm-none-eabi-ld --entry=__start -nostartfiles -nodefaultlibs -g -Map=/usr/src/uros_ws/firmware/spresense/sdk/nuttx.map --cref --defsym __stack=_vectors+1572864 -T/usr/src/uros_ws/firmware/spresense/sdk/bsp/scripts/ramconfig.ld -L"/usr/src/uros_ws/firmware/spresense/sdk/lib" -L"/usr/src/uros_ws/firmware/spresense/sdk/bsp/board"  -L"/usr/src/uros_ws/firmware/spresense/sdk/bsp" \
-o "/usr/src/uros_ws/firmware/spresense/sdk/nuttx"   \
--start-group -lbsp -lsystem -lextdrivers -llte -lexamples -lapps -lsched -ldrivers -lconfigs -lc -lmm -larch -lcxx -lapps -lnet -lfs -lbinfmt -lgraphics -lnx -lcxx -lboard "/usr/local/bin/../lib/gcc/arm-none-eabi/7.3.1/../../../../arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libm.a"  -lsupc++ "/usr/local/bin/../lib/gcc/arm-none-eabi/7.3.1/thumb/v7e-m/fpv4-sp/hard/libgcc.a" --end-group
4

1 回答 1

0

您必须重命名您在应用程序中引用 nothrow 的方式。文件.a是已经编译的库,因此除非您能够修改它并再次编译它,否则它是不可修改的(因此有符号和引用)。

编译器使用命名空间创建唯一引用(名称 mangling,查看此示例https://godbolt.org/z/cPkvxm)。所以你必须使用std::nothrow(使用它定义的命名空间),否则,你正在调用另一个(可能是未定义的)符号。

如果nothrow不包含命名空间,您可以像现在一样使用它,但是,如果将来您决定创建自己的命名空间,您将nothrown遇到冲突(很容易解决,但需要时间以及诸如 nothrownCustom/Customnothrown/nothrown_custom/etc 之类的东西,而不是 Custom::nothrown)。

PD:为整个文件使用命名空间是一个非常简单的解决方法,但在这样做之前先看看这篇文章:为什么“使用命名空间 std;” 被认为是不好的做法?

于 2020-04-04T21:50:52.080 回答