未定义的符号:运行时_ZN7QString13toUtf8_helperERKS_

Undefined symbol: _ZN7QString13toUtf8_helperERKS_ at runtime

本文关键字:ZN7QString13toUtf8 helperERKS 运行时 符号 未定义      更新时间:2023-10-16

我有两个使用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/libLD_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中的值相同。如果是这种情况,那么您有两种选择。

  1. 要么分两步完成,即 QString().toStdString()和在下一步中将其转换为const char*。虽然不是干净,但它有效。(主要问题是有"深拷贝"。当你将 QString 转换为 std::string,Qt 创建一个临时对象并直接尝试读取此临时对象。使用此方法,您将创建两个单独的对象。
  2. 使用QString().toAscii.constData()QString():toUtf8().constData()(最好)

从外观上看,您遇到的不是编译错误,而是链接错误。您还没有向我们展示正在使用的链接命令,您应该检查它们是否不同。要正确使用QString方法,您必须链接到QtCore。

您使用的是哪种构建系统?想从命令行尝试吗?如果你自己编译呢?我读了你的一些评论,你似乎已经用ldd检查了可执行文件,它们两个的输出是一样的吗?

此外,这些标志:-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB,它们可能会有所作为,您也应该尝试在 Eclipse 项目中定义这些标志。

Qt

的库可能很复杂,可以在没有适当的构建系统的情况下徒手使用(例如,您在Eclipse项目中缺少适当的定义),特别是如果您打算使用QtQuick或打算将来构建到Android。我会选择qmakeCMake。如果您的计划是支持不同的 IDE,CMake 是值得的,因为它可以为其中大多数生成项目。

相关文章:
  • 没有找到相关文章