C++ 未定义的符号:_zn7qstring13tout08_helperworks_u在运行时

C++ 未定义的符号:_zn7qstring13tout08_helperworks_u在运行时,c++,eclipse,qt,gcc,C++,Eclipse,Qt,Gcc,我有两个使用Qt的项目。一个是用QtCreator开发的,另一个是用eclipse开发的。两者都使用相同的Qt5.3.1库,都是用GCC编译的。但是,当我运行eclipse中的程序时,它会崩溃,并显示消息Undefined symbol:\u zn7qstring13tof8\u helperworks\u 查找表明,产生此错误的代码是 path.toStdString().c_str() // path is a QString 在qstring.h中的确切位置是 #if defin

我有两个使用Qt的项目。一个是用QtCreator开发的,另一个是用eclipse开发的。两者都使用相同的Qt5.3.1库,都是用GCC编译的。但是,当我运行eclipse中的程序时,它会崩溃,并显示消息
Undefined symbol:\u zn7qstring13tof8\u helperworks\u

查找表明,产生此错误的代码是

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()); }
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
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
Edit2: 链接器输出如下所示:

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"
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++ -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
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

我假设您想使用QString.toStdString().c_str()函数将
QString
转换为
const char*
。这不是一种可靠的方法。我不知道文档是怎么说的,但我尝试使用这个函数获取文件位置,它给了我一些奇怪的东西。请检查const char*是否与QString中的值相同。如果是这种情况,那么您有两个选择

  • 或者分两步进行。i、 e.
    QString().tostString()
    和 在下一步中,将其转换为
    常量字符*
    。虽然不是 干净,但它能工作。(主要问题是“深度复制”。当您 将QString转换为std::string,Qt创建一个临时对象并直接 尝试读取此临时对象。使用此方法,您将创建两个临时对象 分开的对象
  • 使用
    QString().toAscii.constData()
    QString():toUtf8().constData()
    (首选)

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

    您使用的是哪个构建系统?注意从命令行尝试吗?如果您自己编译它会怎么样?我读了您的一些评论,您似乎用
    ldd
    检查了可执行文件,它们的输出是否相同

    此外,这些标志:
    -DQT\u WIDGETS\u LIB-DQT\u GUI\u LIB-DQT\u CORE\u LIB
    ,它们可能会有所不同,您也应该尝试在Eclipse项目中定义它们


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

    未定义的符号:\u zn7qstring13tout08\u helperworks\u
    可能是由以下原因造成的:

    由于缺少
    -Wl,-rpath、/usr/local/Qt-5.3.1/lib
    LD\u LIBRARY\u 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_可重入-fPIE-DQT_小部件库-DQT_GUI库
    
    -DQT_CORE_LIB-I/usr/local/Qt-5.3.1/mkspecs/linux-g++
    qmake/cmake
    是一个不错的选择。但有趣的是,看看链接器是如何成功的,然后在运行过程中,我们会得到一个未定义的引用(不是一个不匹配的dll案例)。特别是因为QT中没有针对
    toUtf8\u helper
    的预处理器保护。请再试一次。您可以添加
    -DQT\u compile\u QSTRING\u COMPAT\u CPP
    ,以便我们在部分使用
    toUtf8()
    时采用稍微不同的路径,而不调用缺少的
    toUtf8\u helper
    方法

    原因:我假设这是因为在构建项目期间,QtCore dll使用一组不匹配的预处理器标志进行构建。然后,代码中包含的头文件,如
    qstring.h
    ,具有内联函数,由预处理器定义保护,如
    toUtf8()在
    toStdString()期间调用的
    将采用不同的路径


    还请注意,不建议尝试使用此问题/答案中的
    qmake/cmake
    文件构建QT项目,这势必会在项目中造成更多问题。

    如果您是对的,那么
    QString::toUtf8().constData()
    是将
    QString
    转换为
    const char*
    的更优雅的方法,它仍然会产生此错误,以及您的其他建议。从QString到Utf8的转换似乎有问题,并且它也用于转换为
    std::string
    。顺便说一句,QString::toAscii()从Qt5起不再存在。您是通过两个不同的步骤实现它的吗?例如qstring到stdstring和从stdstring到const char*?如果是,它何时崩溃?是的,
    std::string spath=path.toStdString();
    转换为
    std::string
    时崩溃。您尝试转换的字符串是英文的吗?它是文件系统中的一个路径。我刚刚检查了它,它没有非Ascii字符。我不确定,所以我将写注释而不是答案。当带有这些符号的源文件不包含在c中时,会出现未定义符号错误完整的源代码。@fnc12我不确定我是否理解正确:源代码头中有
    QString::toUtfHelper
    的符号,但在编译的库中没有。但我使用的是
    make install
    复制到
    /usr/local/Qt-5.3.1
    的源文件,以及位于同一文件夹中的库(我用
    ldd
    )检查了它。这里怎么会有不一致的地方?而且,另一个项目使用相同的文件,没有错误。使用Qt静态