未定义的符号:运行时_ZN7QString13toUtf8_helperERKS_
Undefined symbol: _ZN7QString13toUtf8_helperERKS_ at runtime
我有两个使用Qt的项目。一个是用QtCreator开发的,另一个是用eclipse开发的。两者都使用相同的Qt 5.3.1库,都是用GCC编译的。但是,当我运行日食中的程序时,它会崩溃并显示消息Undefined symbol: _ZN7QString13toUtf8_helperERKS_
。
查找显示产生此错误的代码是
path.toStdString().c_str() // path is a QString
Qstring.h 中的确切位置是
#if defined(Q_COMPILER_REF_QUALIFIERS) && !defined(QT_COMPILING_QSTRING_COMPAT_CPP)
QByteArray toLatin1() const & Q_REQUIRED_RESULT
{ return toLatin1_helper(*this); }
QByteArray toLatin1() && Q_REQUIRED_RESULT
{ return toLatin1_helper_inplace(*this); }
QByteArray toUtf8() const & Q_REQUIRED_RESULT
{ return toUtf8_helper(*this); } // <- here
QByteArray toUtf8() && Q_REQUIRED_RESULT
{ return toUtf8_helper(*this); }
QByteArray toLocal8Bit() const & Q_REQUIRED_RESULT
{ return toLocal8Bit_helper(constData(), size()); }
QByteArray toLocal8Bit() && Q_REQUIRED_RESULT
{ return toLocal8Bit_helper(constData(), size()); }
将QString
转换为另一个项目(QtCreator 中的项目)中的std::string
就可以了。可能有什么问题?日食中是否缺少任何编译器选项?
编辑:两个项目的示例文件的编译器输出是(为了可读性,我添加了换行符):
日蚀
Building file: ../src/mysource1.cpp
Invoking: GCC C++ Compiler
g++ -I"/home/username/myfolder/myproject1/src"
-I"/home/username/myfolder/myproject1/src/dialogs"
-I"/home/username/myfolder/myproject1/src/ignore"
-I/usr/local/Qt-5.3.1/include -I/usr/local/Qt-5.3.1/include/QtCore
-I/usr/local/Qt-5.3.1/include/QtGui -I/usr/local/Qt-5.3.1/include/QtWidgets
-O0 -g3 -Wall -c -fmessage-length=0 -std=c++0x -fPIE -MMD -MP
-MF"src/mysource1.d" -MT"src/mysource1.d" -o "src/mysource1.o"
"../src/mysource1.cpp"
QtCreator
g++ -c -pipe -g -Wall -W -D_REENTRANT -fPIE -DQT_WIDGETS_LIB -DQT_GUI_LIB
-DQT_CORE_LIB -I/usr/local/Qt-5.3.1/mkspecs/linux-g++ -I../myproject2
-I../myproject2/src -I../myproject2/src/data -I../myproject2/src/dialogs
-I../myproject2/src/widgets -I../myproject2/src/widgets/overlays
-I../myproject2/src/widgets/tools -I/usr/local/Qt-5.3.1/include
-I/usr/local/Qt-5.3.1/include/QtWidgets -I/usr/local/Qt-5.3.1/include/QtGui
-I/usr/local/Qt-5.3.1/include/QtCore -I. -I. -o mainwind.o
../myproject2/src/mainwind.cpp
编辑2:链接器输出如下所示:
日蚀
Invoking: GCC C++ Linker
g++ -L/usr/local/Qt-5.3.1/lib -o "myproject1" /*list of .o files*/
-lQt5Core -lQt5Gui -lQt5Widgets -lgit2
QtCreator
g++ -Wl,-rpath,/usr/local/Qt-5.3.1/lib -o myproject2 /*list of .o files*/
-L/usr/local/Qt-5.3.1/lib -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
qmake/cmake
是要走的路。但是有趣的是,看看链接器是如何成功的,然后在运行过程中,我们得到了一个未定义的引用(而不是不匹配的dll情况)。特别是因为 QT github 存储库中没有用于toUtf8_helper
的预处理器保护。再试一次。您能否添加-DQT_COMPILING_QSTRING_COMPAT_CPP
,以便我们对 #else 部分中的toUtf8()
采取略有不同的路径,并且不调用缺少的toUtf8_helper
方法。
原因:我认为这是因为 QtCore dll 是使用一组预处理器标志构建的,这些标志在项目构建期间不匹配。然后,代码中包含的头文件(如qstring.h
)具有内联函数,受预处理器定义的保护,如 for toUtf8()
在toStdString()
期间调用,将采用不同的路径。
另请注意,不建议尝试像本问题/答案中那样使用qmake/cmake
文件构建 QT 项目,这势必会在项目中引起更多问题。
Undefined symbol: _ZN7QString13toUtf8_helperERKS_
可能是由以下原因引起的:
由于缺少-Wl,-rpath,/usr/local/Qt-5.3.1/lib
或LD_LIBRARY_PATH
,在 eclipse 中链接到错误(过时的 Qt 库)。Eclipse 构建环境未设置为QtCreator构建环境。
您写道,您已使用 ldd
检查了应用程序的动态链接,但您还应该在 eclipse 中添加缺少的链接器选项-Wl,-rpath,/usr/local/Qt-5.3.1/lib
。
(另一种选择是使用 LD_LIBRARY_PATH,但保持两个构建环境相同是合理的。 LDD 和应用程序一样受到LD_LIBRARY_PATH的影响。 LD_LIBRARY_PATH可能无法正确导出?
还要添加编译器标志-D_REENTRANT -fPIE -DQT_WIDGETS_LIB -DQT_GUI_LIB
-DQT_CORE_LIB -I/usr/local/Qt-5.3.1/mkspecs/linux-g++
我假设你想使用QString.toStdString().c_str()函数将QString
转换为const char *
。这不是一种可靠的方法。我不知道文档说了什么,但我尝试使用此功能获取文件位置,它给了我一些奇怪的东西。请检查常量字符*是否与您在QString中的值相同。如果是这种情况,那么您有两种选择。
- 要么分两步完成,即
QString().toStdString()
和在下一步中将其转换为const char*
。虽然不是干净,但它有效。(主要问题是有"深拷贝"。当你将 QString 转换为 std::string,Qt 创建一个临时对象并直接尝试读取此临时对象。使用此方法,您将创建两个单独的对象。 - 使用
QString().toAscii.constData()
或QString():toUtf8().constData()
(最好)
从外观上看,您遇到的不是编译错误,而是链接错误。您还没有向我们展示正在使用的链接命令,您应该检查它们是否不同。要正确使用QString
方法,您必须链接到QtCore。
您使用的是哪种构建系统?想从命令行尝试吗?如果你自己编译呢?我读了你的一些评论,你似乎已经用ldd
检查了可执行文件,它们两个的输出是一样的吗?
此外,这些标志:-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB
,它们可能会有所作为,您也应该尝试在 Eclipse 项目中定义这些标志。
的库可能很复杂,可以在没有适当的构建系统的情况下徒手使用(例如,您在Eclipse项目中缺少适当的定义),特别是如果您打算使用QtQuick或打算将来构建到Android。我会选择qmake或CMake。如果您的计划是支持不同的 IDE,CMake 是值得的,因为它可以为其中大多数生成项目。
- 没有找到相关文章