web-dev-qa-db-ja.com

未解決の外部シンボル「public:virtual struct QMetaObject const * __thiscall Parent

QObjectからクラスを継承しました:

class Parent: public QObject
{
    Q_OBJECT
    QObject* cl;

public:
    Parent(QObject *parent=0):QObject(parent) {
        cl = NULL;
    }

    QObject* getCl() const {
        return cl;
    }
    void setCl(QObject *obj) {
        cl = obj;
    }
};

しかし、私が書くとき:

Parent ev;

次のエラーが表示されます。

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall Parent::metaObject(void)const " (?metaObject@Parent@@UBEPBUQMetaObject@@XZ)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __thiscall Parent::qt_metacast(char const *)" (?qt_metacast@Parent@@UAEPAXPBD@Z)

main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __thiscall Parent::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@Parent@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
62

この問題を修正するには、アプリケーションのdebugフォルダーを削除し、再度実行する必要があります。

67

Visual Studioを使用している場合は、Q_OBJECTヘッダーファイルから、ファイルを保存し、Q_OBJECTヘッダーファイルに戻り、ファイルを再度保存します。これにより、moc_*ファイルを作成し、正しくビルドしてリンクする必要があります。

57
MPicazo

いくつかの答えはVisual Studioに基づいていることに気付きました。

この回答はQt Creatorに基づいています。

名前とは異なり、Rebuild Projectは、すべてを消去してゼロから構築するわけではありません。クラスにQObject(および/またはQ_OBJECT)を最近追加した場合は、qmakeを再度実行する必要があります。

  1. クリーンプロジェクト
  2. Qmakeを実行する
  3. ビルドプロジェクト

これは、デフォルトでは、qmakeが実行されるのは、新しいソースファイルを追加したり、.proファイル。既存のファイルを編集した場合、qmakeを実行する必要があることはわかりません。

フォールバックとして、Qtをブルートフォースですべてをゼロから構築するには、DebugまたはReleaseフォルダーを削除します。

30
Stephen Quan

そのため、問題は.hファイルをコンパイルするためにQt MOCコンパイラが必要だったことです。これは、QObjectまたはその子の1つを拡張するクラスに必要です。修正には(私にとって)ヘッダーファイルを右クリックして[プロパティ]を選択し、アイテムタイプを[Qt MOC Input]に設定し、ヘッダーで[Compile]を押して、結果のmoc_myfilename.cppファイルをmy事業。

9
Vern Jensen

Visual Studioプロジェクトでmocファイルが生成された場合、それらがプロジェクトに含まれていない場合はプロジェクトに含めてから再構築してください。

7
Akın Yılmaz

Visual Studioでも同じ問題が発生したため、次の手順を実行して解決しました。

  1. ソリューションエクスプローラーでヘッダーファイルを右クリックします
  2. 物性
  3. 「アイテムタイプ」を「カスタムビルドツール」に変更します

次に、カスタムビルドツールの構成で:

  1. 一般に移動
  2. 「コマンドライン」を次のように設定します。

    "$(QTDIR)\ bin\moc.exe" "%(FullPath)" -o "。\ GeneratedFiles\$(ConfigurationName)\ moc _%(Filename).cpp" "-fStdAfx.h" "-f ../ ../../src/FileName.h」-DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NET_WORK -DWIN32_LEAN_AND_MEAN -DDIS_VERSION = 7 -D_MATH_DEFINES_DEFINED "-I。\ SFML_STATIC" "-I。\ GeneratedFiles" "-I。" 「-I $(QTDIR)\ include」「-I。\ GeneratedFiles\$(ConfigurationName)」 "-I $(QTDIR)\ include\QtCore" "-I $(QTDIR)\ include\QtGui" "-I $(QTDIR)\ include\QtNetwork"

  3. 「出力」を次のように設定します。

    。\ GeneratedFiles\$(ConfigurationName)\ moc _%(Filename).cpp

  4. 「追加の依存関係」を次のように設定します。
    $(QTDIR)\ bin\moc.exe;%(FullPath)


正確な値は異なる場合があります。通常、Qtプラグインを介して適用されます。

6
Trevor Hickey

CMakeを使用してQtプロジェクトを管理し、QT4_WRAP_CPP呼び出しの下に新しいQ_OBJECTを追加する必要があります。これにより、プロジェクトに含めるmoc _ *。cxxが生成され、未解決の外部がクリーンアップされます。

4
whatnick

CppファイルにQ_OBJECTクラス定義があると、Visual Studio 2012でこの問題が発生しました。クラス定義をヘッダーファイルに移動すると、問題が解決しました。

Mocにcppファイルを追加することで、cppファイルでQ_OBJECTクラスをサポートできるように見えますが、私はこれを試しませんでした。

3
Edward

プロジェクトにcpp/uiファイルを手動で追加しましたが、ヘッダーファイルをヘッダーファイルとして明示的に追加するのを忘れていました。コンパイル時に、上記と同様のエラーメッセージが表示され、ビルドのデバッグ(またはリリース)ディレクトリにmoc _ *。cppファイルが生成されませんでした。それはそれほど明白な間違いではなく、qmakeは文句を言わず、リンカーメッセージ以外にエラーはありませんでした。

だから誰かが再び同じ問題に出くわした場合(または同じコピーと間違えた場合):ヘッダーファイルもプロジェクトファイルに追加されていることを確認してください

2

私の問題は、Qtマクロを使用していたファイルの1つがmocされていないことでした。 Qt Plugin for Visual StudioはQ_NAMESPACEマクロを認識しないため、ファイルをmoc'ingリストに追加しないことがわかりました。

そのため、 this answer のソリューションを使用して、ファイルをマイキングリストに追加しました。

「moc_ *」を正常に生成した.hファイルを見つけ、「Custom Build Tool-> General」のすべての内容を新しい.hファイル設定ページにコピーします。

DebugRelease- Modeの異なるオプションに注意してください。

その後、プロジェクトをビルドします。

DebugおよびRelease- Modeでそれぞれ1回ビルドします

最後に、生成された「moc_ *」ファイルをプロジェクトに追加します。

これで、「moc_filename.cpp」はGenerated Files\DebugおよびGenerated Files\Releaseにあるはずです。

それぞれを右クリックして、ヘアプロパティを変更します。

  • Debugのファイル:構成をReleaseに変更してから、General->Excluded from buildyesに変更します。
  • Releaseのファイル:構成をDebugに変更してから、General->Excluded from buildyesに変更します。
1
Darkproduct

私の場合(VS2012およびQt v4.8.4でQtAdd-inを使用)、上記の提案はいずれも機能しませんでした。何らかの理由でVSは適切なmocファイルを生成できませんでした(ビルド出力:関連するクラスが見つかりません。出力は生成されませんでした)。 。

動作したのは、必要なすべてのmocsをコマンドライン(moc -o moc_SomeClass.cpp SomeClass.h)からコンパイルし、GeneratedFilesフォルダー内の間違ったmocsを置き換えることでした。

これは、プロジェクトを正常にビルドするための回避策であり(大きなプロジェクトには便利ではありません)、実際には奇妙なVS/QtAdd-inの動作を説明するものではありません。

1
dianull

QtAdd-inをVS2010で使用すると、moc _ *。cppファイルがGeneratedFiles/Debugフォルダーで更新されていることに気付きましたが、私はリリースモードでした。ファイルをReleaseフォルダーにコピーするとうまくいきました。

1
zengaja

[〜#〜] pimpl [〜#〜] "(プライベート実装)プログラミングパターンを使用するときにQtで「プライベートクラス」を使用すると、この問題が発生しました。 Qtはソースコード全体でこのモデルを使用します。私は自分でそれを本当に好きになりました。

この手法では、パブリックヘッダーファイルで「プライベート」前方宣言クラスを使用します。これは、「パブリック」クラス(つまり「親」)によって使用されます。親は、データメンバーとしてプライベートクラスのインスタンスへのポインターを持ちます。

「プライベート」クラスは、パブリッククラスのcppファイル内で完全に定義されます。プライベートクラス用のヘッダーファイルはありません。

「汚い仕事」のすべては、そのプライベートクラスで行われます。これにより、他のすべてのプライベートメンバー(データと関数の両方)を含むパブリッククラスのすべての実装が非表示になります。

特に内部Qtソースを読む予定がある場合は、PIMPLパターンについて学ぶことを強くお勧めします。

そのコーディングスタイルをさらに説明することなく、この質問に関連するポイントを以下に示します... Q_OBJECTマクロは、シグナル/スロットなどを使用できるQObjectである「プライベート」クラスのcpp内で動作します。cpp内のパブリッククラスに.mocを明示的に含める必要があります

#include "MyPublicClass.moc"

この行に関するIDE警告は無視できます。

それがまったく手に負えないかどうかはわかりませんが、そのインクルードは、cppの最上部ではなく、プライベートクラス定義の後に行われます(インクルードが通常配置されるように)。したがって、cppレイアウトは次のようになります。

  1. 「通常」インクルードが定義されています。
  2. プライベートクラスが定義されます。
  3. パブリッククラスのmocは#includedです。
  4. パブリッククラスの実装が定義されています。
1
BuvinJ

どちらの答えも、VS 2013環境で機能します。最終的に、プロジェクトから。h /。cppを削除し、追加し直すことで問題を解決しました。

0
Adam Woo

これは最近、MingWからMSVCに切り替えたときに起こりました。クラスとしてリストされたプロトタイプのクラス/構造がありましたが、MingWは気にしませんでした。

MSVCは、プロトタイピングに関して、classstructの違いを明確に認識しています。

それがいつか他の誰かを助けることを願っています。

0
phyatt

私にとって、これが原因です:QTのプロジェクトファイルに含まれていないヘッダーまたはソースファイル

0
Sanbrother

私はこれが非常に古い質問であることを知っていますが、それはまだ興味深いようです(私は最後の月に少なくとも4〜5回ここにいました)、このエラーを得ることができる別の理由を見つけたようです。

私の場合、ヘッダーファイルに間違って入力しました:

#include "MyClass.h""

出力全体を調べて初めて、その行でコンパイラが警告を発していることがわかりました。

追加の引用符を削除したので、QObjectは完全にコンパイルされます!

0
Brutus

私の場合、上記のいずれも機能しませんでしたが、それは完全に私の間違いでした。

.hファイルの仮想関数をオーバーライドしました(宣言しました)が、.cppでそれらを定義したことはありませんでした:)

0
zar

私は同じ問題を抱えています、私の解決策はエンコーディングでした(「UTF16LE BOM」のファイルはmoc.exeで生成できません)、y ASCII encondingで別のファイルを作成して動作します。

HxD HexEditorは、体系化を確認するのに役立ちます。

0

これをヘッダーファイルに追加して問題を解決しました。

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif
0
Nadjib Dz

VS2015で統合されたPerforce p4vクライアントを使用しています。私の場合、Perforceはmocファイルをデポに追加しようとしましたが、この操作を元に戻すと、Perforceはこのmocファイルをプロジェクトから削除して削除しました。ファイルは次のコンパイル後に再作成されましたが、プロジェクトに含まれていませんでした。生成されたファイルに手動で追加する必要があります。

0
Flot2011