未定义的符号:_ZN7QString13toUtf8_helperERKS_在运行时

Ant*_*kiy 5 c++ eclipse qt gcc

我有两个使用Qt的项目.一个是用QtCreator开发的,另一个是用eclipse开发的.两者都使用相同的Qt 5.3.1库,两者都是用GCC编译的.但是,当我运行eclipse中的程序时,它会与消息崩溃Undefined symbol: _ZN7QString13toUtf8_helperERKS_.

查找显示产生此错误的代码是

path.toStdString().c_str()     // path is a QString
Run Code Online (Sandbox Code Playgroud)

并且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()); }
Run Code Online (Sandbox Code Playgroud)

转换QStringstd::string在其他项目(一个在QtCreator)的作品就好了.可能是什么问题?eclipse中是否缺少任何编译器选项?

编辑: 两个项目中的示例文件的编译器输出是(为了便于阅读,我添加了换行符):

日食

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"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Edit2: 链接器输出如下:

日食

Invoking: GCC C++ Linker
g++ -L/usr/local/Qt-5.3.1/lib -o "myproject1" /*list of .o files*/
    -lQt5Core -lQt5Gui -lQt5Widgets -lgit2
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Kir*_*ran 7

qmake/cmake是要走的路.但有趣的是看到链接器如何成功,然后在运行期间,我们得到一个未定义的引用(不是一个不匹配的DLL案例).特别是因为toUtf8_helper在QT github repo中没有预处理器保护.再试一次.您可以添加-DQT_COMPILING_QSTRING_COMPAT_CPP,这样,我们就用略微不同的路径toUtf8()的#else一部分,而不是调用缺少的toUtf8_helper方法.

原因:我认为这是因为QtCore dll是使用一组预处理程序标志构建的,这些标记在项目构建期间未匹配.然后,qstring.h代码中包含的头文件(具有内联函数)受到预处理程序定义的保护,就像在toUtf8()调用期间一样,toStdString()将采用不同的路径.

另请注意,qmake/cmake不建议尝试使用out 问题构建QT项目,因为这个问题/答案不会被建议,并且必然会导致项目中出现更多问题.

  • 在我的情况下,它是`-DQT_COMPILING_QSTRING_COMPAT_CPP` - 以防万一其他人偶然发现这一点. (3认同)