[Qt4]VS2010編譯提示error LNK2001: unresolved external symbol "public: virtual struct QMetaObject等錯誤解決方案


剛學習Qt4編程,在編譯一個小程序的時候出現了鏈接錯誤。


報錯如下

1>—— 已啓動全部重新生成: 項目: Test, 配置: Debug x64 ——
1> FindDialog.cpp
1> main.cpp
1> Generating Code…
1>FindDialog.obj : error LNK2001: unresolved external symbol “public: virtual struct QMetaObject const * __cdecl FindDialog::metaObject(void)const ” (?metaObject@FindDialog@@UEBAPEBUQMetaObject@@XZ)
1>FindDialog.obj : error LNK2001: unresolved external symbol “public: virtual void * __cdecl FindDialog::qt_metacast(char const *)” (?qt_metacast@FindDialog@@UEAAPEAXPEBD@Z)
1>FindDialog.obj : error LNK2001: unresolved external symbol “public: virtual int __cdecl FindDialog::qt_metacall(enum QMetaObject::Call,int,void * *)” (?qt_metacall@FindDialog@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
1>FindDialog.obj : error LNK2001: unresolved external symbol “public: static struct QMetaObject const FindDialog::staticMetaObject” (?staticMetaObject@FindDialog@@2UQMetaObject@@B)
1>FindDialog.obj : error LNK2019: unresolved external symbol “protected: void __cdecl FindDialog::findNext(class QString const &,enum Qt::CaseSensitivity)” (?findNext@FindDialog@@IEAAXAEBVQString@@W4CaseSensitivity@Qt@@@Z) referenced in function “private: void __cdecl FindDialog::findClicked(void)” (?findClicked@FindDialog@@AEAAXXZ)
1>FindDialog.obj : error LNK2019: unresolved external symbol “protected: void __cdecl FindDialog::findPrevious(class QString const &,enum Qt::CaseSensitivity)” (?findPrevious@FindDialog@@IEAAXAEBVQString@@W4CaseSensitivity@Qt@@@Z) referenced in function “private: void __cdecl FindDialog::findClicked(void)” (?findClicked@FindDialog@@AEAAXXZ)
1>C:\Users\Grey\Desktop\Test\x64\Debug\Test.exe : fatal error LNK1120: 6 unresolved externals
========== 全部重新生成: 成功 0 個,失敗 1 個,跳過 0 個 ==========


原因
  對於所有定義了信號和槽的類,在類定義的開始處的Q_OBJECT宏都是必需的。由於FindDialog類的定義包含Q_OBJECT宏,因而由qmkae生成的makefile將會自動包含一些運行moc的規則,moc(meta-object compiler)是Qt的元對象編譯器。

                     Qt的元對象系統
 Qt的主要成就之一就是使用了一種機制對C++進行了擴展,並且使用這種機制創建了獨立的軟件組件。這些組件可以綁定在一起,但任何一個組件對於它所要連接的組件的情況事先都一無所知。

 這種機制稱爲元對象系統(meta-object system),它提供了關鍵的兩項技術:信號-槽以及內省(introspection)。內省功能對於實現信號和槽是必需的,並且允許應用程序的開發人員在運行時獲得有關QObject子類的“元信息”(meta-infomation),包括一個含有對象的類名以及它所支持的信號和槽的列表。這一機制也支持屬性(廣泛用於Qt設計師中)和文本翻譯(用於國際化),並且它也爲QtScript模塊奠定了基礎。從Qt4.2開始,可以動態添加屬性。

 標準C++沒有對Qt的元對象系統所需要的動態元信息提供支持。Qt通過提供一個獨立的moc工具解決了這個問題,moc解析Q_OBJECT類的定義並且通過C++函數來提供可供使用的信息。由於moc使用純C++來實現它的所有功能,所以Qt的元對象系統可以在任意C++編譯器上工作。

 由於程序中使用了Q_OBJECT宏來定義類,所以必須運行moc來生成用於由Q_OBJECT聲明的所有函數和所有信號的實現。


解決方案
將cmd目錄跳到工程文件目錄下,然後執行cmd命令(moc.exe是Qt下的工具,執行命令前保證Qt的bin目錄已經添加到系統環境變量PATH中):

moc FindDialog.h –o moc_FindDialog.cpp

同目錄下會生成一個moc_FindDialog.cpp文件,將該文件添加到VS工程中即可編譯通過。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章