Cannot mix incompatible Qt library (version 0x1040704) with this library (version 0x40704)。
报告这个错误的代码位于 QObjectPrivate 的构造函数中:
if (version != QObjectPrivateVersion )
qFatal( "Cannot mix incompatible Qt library (version 0x%x) with this library (version 0x%x)" ,
version, QObjectPrivateVersion );
在系统已经安装咯一个QT版本的情况下,如果在编译程序的时候,链接到QtSDK自带的库文件的话,则在运行时就可能出现这种情况。
原因是KDE组织在开发过程中针对自己的需要修改咯QT的代码,为咯表示自己使用的QT已经不是诺基亚提供的QT咯,于是就修改咯QT中的头文件qglobal.h,将 QObjectPrivateVersion 改成QT_VERSION + 0x1000000,而在原始的QT版本中, QObjectPrivateVersion 与QT_VERSION是相等的。这样修改的效果,就是从字面上来看,主版本号的04 前面多咯1.例如,对于QT4.7.4 版本,原始的QT代码中, QObjectPrivateVersion=0x040704 ,而KDE组织修改过的QT代码中, QObjectPrivateVersion=0x1040704 。具体的补丁是0209-prevent-qt-mixing.diff:
qt-bugs@ issue : none
Trolltech task ID : none
bugs.kde.org number : none
applied: yes
author: Lubos Lunak <l.lunak@kde.org>
This patch changes QObjectPrivateVersion, thus preventing mixing
parts of upstream Qt and qt-copy. In general it is a bad idea to mix
e.g. libQtCore from one build and libQtGui from another one, and other
qt-copy patches could make changes in Qt internal structures that could
cause problems when mixed with upstream Qt.
This patch does not make qt-copy binary incompatible with upstream Qt.
It only further enforces using the same sources for the whole Qt build.
--- src/corelib/kernel/qobject_p.h.sav 2008-01-29 19:37:26.000000000 +0100
+++ src/corelib/kernel/qobject_p.h 2008-01-30 14:08:15.000000000 +0100
@@ -75,7 +75,9 @@ extern QSignalSpyCallbackSet Q_CORE_EXPO
inline QObjectData::~QObjectData() {}
-enum { QObjectPrivateVersion = QT_VERSION };
+// add 0x1000000 to mark it as qt-copy version, with possible modifications
+// in some Q*Private class
+enum { QObjectPrivateVersion = QT_VERSION + 0x1000000 };
class Q_CORE_EXPORT QObjectPrivate : public QObjectData
{
与QtSDK中自带的库链接在一起的程序,在实际运行过程中,可能會出现某些问题,导致系统在为妳的程序载入动态库时,先载入咯QtSDK中的一部分库(原始版本的QT),然后又载入咯系统中已有的一部分库(KDE修改过的QT),然后在QT自身的检查代码中,发现二者的版本号不一致,于是报错退出。例如,在本座用的MagicLinux上:
bash-4.0# ldd /usr/bin/ShutDownAt2100
……
libQtGui.so.4 => /Data/Main/程序/QtSDK/Desktop/Qt/474/gcc/lib/libQtGui.so.4 (0xb6bb0000)
libQtNetwork.so.4 => /Data/Main/程序/QtSDK/Desktop/Qt/474/gcc/lib/libQtNetwork.so.4 (0xb6a61000)
libQtCore.so.4 => /Data/Main/程序/QtSDK/Desktop/Qt/474/gcc/lib/libQtCore.so.4 (0xb678e000)
……
bash-4.0# strace ShutDownAt2100
execve("/usr/bin/ShutDownAt2100", ["ShutDownAt2100"], [/* 54 vars */]) = 0
……
open("/Data/Main/\347\250\213\345\272\217/QtSDK/Desktop/Qt/474/gcc/lib/libQtGui.so.4", O_RDONLY) = 3
……
open("/Data/Main/\347\250\213\345\272\217/QtSDK/Desktop/Qt/474/gcc/lib/libQtNetwork.so.4", O_RDONLY) = 3
……
open("/Data/Main/\347\250\213\345\272\217/QtSDK/Desktop/Qt/474/gcc/lib/libQtCore.so.4", O_RDONLY) = 3
……
open("/usr/lib/qt4/lib/libQtDBus.so.4", O_RDONLY) = 8
……
write(2, "Cannot mix incompatible Qt librar"..., 91Cannot mix incompatible Qt library (version 0x1040704) with this library (version 0x40704)
) = 91
rt_sigprocmask(SIG_UNBLOCK, [ABRT], NULL, 8) = 0
tgkill(4537, 4537, SIGABRT) = 0
--- SIGABRT (Aborted) @ 0 (0) ---
+++ killed by SIGABRT +++
bash-4.0#
可以看到,程序没有链接libQtDBus.so.4,结果系统在运行时优先在KDE的库目录里找到咯libQtDBus.so.4,结果就导致其中的 QObjectPrivate类在构造函数中报错退出。
目前本座知道的解决方法有两种:
1. 运行时使用环境变量指定动态库的目录:
bash-4.0# ShutDownAt2100
Cannot mix incompatible Qt library (version 0x1040704) with this library (version 0x40704)
已放弃
bash-4.0# LD_LIBRARY_PATH="/Data/Main/程序/QtSDK/Desktop/Qt/474/gcc/lib/";ShutDownAt2100 &
[1] 5245
bash-4.0# Object::connect: No such slot ShutDownAt2100::ReadExternalServer()
Object::connect: (receiver name: 'MainWindow')
QTextStream: No device
QTextStream: No device
bash-4.0#
可看到程序已经运行起来咯。
2. 在编译时直接选择与系统中已有的动态库链接:
在QtSDK中可以按下图操作,以让编译器在链接时链接至系统中已有的QT库。
HxLauncher: Launch Android applications by voice commands