Program Tip

해결되지 않은 외부 기호 "public : virtual struct QMetaObject const * __thiscall Parent

programtip 2020. 11. 22. 20:30
반응형

해결되지 않은 외부 기호 "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)

debug이 문제를 해결하려면 응용 프로그램 폴더를 삭제하고 다시 실행해야합니다.


Visual Studio를 사용하는 Q_OBJECT경우 헤더 파일에서 삭제하고 파일을 저장 한 Q_OBJECT다음 헤더 파일 다시 넣고 파일을 다시 저장합니다. 그러면 moc_*파일 이 생성되고 올바르게 빌드 및 링크됩니다.


일부 답변은 Visual Studio를 기반으로합니다.

이 답변은 Qt Creator를 기반으로합니다.

이름이 제안하는 것과 달리 Rebuild Project모든 것을 지우고 처음부터 빌드하지 않습니다. 최근에 QObject클래스 에 추가 (및 / 또는 Q_OBJECT)했다면 qmake다시 실행 해야합니다. 예 :

  1. 깨끗한 프로젝트
  2. qmake 실행
  3. 프로젝트 구축

이는 기본적으로 qmake새 소스 파일을 추가하거나 파일을 수정하는 등 솔루션을 크게 변경하는 경우에만 실행 되기 때문 .pro입니다. 기존 파일을 편집하는 경우 qmake.

대체로 Qt가 모든 것을 처음부터 빌드하도록 무차별 대입하려면 Debug또는 Release폴더를 삭제하십시오 .


그래서 문제는 .h 파일을 컴파일하기 위해 Qt MOC 컴파일러가 필요하다는 것입니다. 이것은 QObject 또는 그 자식 중 하나를 확장하는 모든 클래스에 필요합니다. 수정은 헤더 파일을 마우스 오른쪽 버튼으로 클릭하고 속성을 선택하고 항목 유형을 "Qt MOC 입력"으로 설정 한 다음 헤더에서 "컴파일"을 누른 다음 결과 moc_myfilename.cpp 파일을 내 계획.


Visual Studio 프로젝트에서 moc 파일이 생성 된 경우 프로젝트에 포함되지 않은 경우 프로젝트에 포함시키고 다시 빌드하십시오.


Visual Studio에서 동일한 문제가 발생했으며 다음 단계를 수행하여 해결했습니다.

  1. 솔루션 탐색기에서 헤더 파일을 마우스 오른쪽 단추로 클릭하십시오.
  2. 속성
  3. "항목 유형"을 "사용자 지정 빌드 도구"로 변경합니다.

그런 다음 Custom Build Tool 구성에서 :

  1. 일반으로 이동
  2. "명령 줄"을 다음과 같이 설정합니다.

    "$ (QTDIR) \ bin \ moc.exe" "% (FullPath)"-o ". \ GeneratedFiles \ $ (구성 이름) \ moc _ % (파일 이름) .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_NETWORK_VERSION = .SFD_NETWORK_LIB -DWIN32_FINEDIC_AND_MEAN_DEML" . \ GeneratedFiles ""-I. " "-I $ (QTDIR) \ include" "-I. \ GeneratedFiles \ $ (구성 이름)." "-I $ (QTDIR) \ include \ QtCore" "-I $ (QTDIR) \ include \ QtGui" "-I $ (QTDIR) \ include \ QtNetwork"

  3. "출력"을 다음으로 설정합니다.

    . \ GeneratedFiles \ $ (구성 이름) \ moc _ % (파일 이름) .cpp

  4. "추가 종속성"을
    $ (QTDIR) \ bin \ moc.exe; % (FullPath)로 설정합니다.


정확한 값은 다를 수 있습니다. 일반적으로 Qt 플러그인을 통해 적용됩니다.


CMake를 사용하여 Qt 프로젝트를 관리하고 QT4_WRAP_CPP 호출 아래에 새 Q_OBJECT를 추가해야합니다. 이렇게하면 프로젝트에 포함 할 moc _ *. cxx가 생성되고 해결되지 않은 외부가 정리됩니다.


내 cpp 파일에 Q_OBJECT 클래스 정의가있을 때 Visual Studio 2012에서이 문제가 발생했습니다. 클래스 정의를 헤더 파일로 이동하면 문제가 해결되었습니다.

moc에 cpp 파일을 추가하여 cpp 파일에서 Q_OBJECT 클래스를 지원할 수있을 것 같지만 시도하지 않았습니다.


cpp / ui 파일을 프로젝트에 수동으로 추가했지만 헤더 파일을 헤더 파일로 명시 적으로 추가하는 것을 잊었습니다. 이제 컴파일 할 때 위와 유사한 오류 메시지가 표시되고 moc _ *. cpp 파일이 빌드의 디버그 (또는 릴리스) 디렉토리에 생성되지 않았습니다. 그것은 명백한 실수가 아니었고, qmake는 불평하지 않았고 링커 메시지 외에는 오류가 없었습니다.

따라서 누군가 같은 문제가 다시 발생하면 (또는 동일한 복사 및 구문 오류를 범하는 경우) : 헤더 파일도 프로젝트 파일에 추가되었는지 확인하십시오.


필자의 경우 (VS2012 및 Qt v4.8.4와 함께 QtAdd-in 사용) 위의 제안 중 어느 것도 작동하지 않았습니다. 어떤 이유로 VS가 적절한 moc 파일을 생성 할 수 없었고 (빌드 출력 : 관련 클래스가 없습니다. 출력이 생성되지 않았습니다.) 직접 관련 헤더를 컴파일했을 때 (qt moc를 컴파일러로 설정하고 '컴파일'을 클릭하면) 빈 moc 파일이 생성되었습니다. .

작업 한 것은 명령 줄 (moc -o moc_SomeClass.cpp SomeClass.h)에서 필요한 모든 moc를 컴파일 한 다음 GeneratedFiles 폴더에서 잘못된 moc를 교체하는 것입니다.

이것은 프로젝트를 성공적으로 빌드하기위한 해결 방법 일뿐 (큰 프로젝트에는 편리한 방법이 아님)이지만 이상한 VS / QtAdd-in 동작을 설명하지는 않습니다.


Using QtAdd-in with VS2010 i realized the moc_*.cpp files were updated in the GeneratedFiles/Debug folder although i was in release mode. Copying the files into the Release folder worked for me.


I've encountered this problem with the use of a "private class" in Qt when employing the "PIMPL" (private implementation) programming pattern. Qt uses this model all through out their source code. I have come to really like it myself.

This technique involves the use of a "private" forward-declared class in a public header file, which will be be used by the "public" class (i.e. it's "parent"). The parent then has a pointer to an instance of the private class as a data member.

The "private" class is defined entirely within the cpp file for the public one. There is NO header file for the private class.

All of the "dirty work" is done with that private class. This hides all of the implementation of your public class including every other private member typically (both data and functions).

I highly recommend learning about the PIMPL pattern - especially if you are going ever read the internal Qt source.

Without explaining that coding style further, here's the point as it relates to this question... To get the Q_OBJECT macro to work inside the cpp for the "private" class to be QObject which can use signals/slot etc., you needed to explicitly include the .moc to the public class inside the cpp:

#include "MyPublicClass.moc"

You can ignore any IDE warnings about this line.

I'm not sure if it matters exactly off hand, but that inclusion I always see done AFTER the private class definition, rather than at the top of the cpp (like includes are typically placed). So, the cpp layout goes like this:

  1. "Normal" includes are defined.
  2. The private class is defined.
  3. The moc for the public class is #included.
  4. The public class implementation is defined.

My problem was that one of my files that used a Qt macro didn't get moc'ed. I found out, that the Qt Plugin for Visual Studio doesn't recognize the Q_NAMESPACE macro and therefore doesn't add the file to the moc'ing list.

So I used the solution from this answer to add the file to the mic'ing list:

You should find a .h file which has successfully generated "moc_*", and copy all the contents in "Custom Build Tool -> General" to the new .h file setting page.

Be careful with the different options for Debug and Release-Mode.

After that, build your project.

Build it once each in Debug and Release-Mode

Finally, add the generated "moc_*" file to your project.

Now, "moc_filename.cpp" should be in Generated Files\Debug and Generated Files\Release.

Right click on each of them and change thair properties:

  • The file in Debug: Change configuration to Release and then change General->Excluded from build to yes.
  • The file in Release: Change configuration to Debug and then change General->Excluded from build to yes.

This happened to me recently when switching from MingW to MSVC. I had a prototyped class/struct listed as a class, and MingW didn't mind.

MSVC definitely sees a difference between class and struct when prototyping is concerned.

Hope that helps someone else one day.


In my case, none of the above worked but it was totally my mistake.

I had overrided virtual functions in .h file (declared them) but had never defined them in .cpp :)


I solved my problem by adding this to my header file :

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif

Either answer works for me in the VS 2013 environment. I eventually solve the problem by removing the .h/.cpp from project, and adding it back.


I am working in VS2015 with an integrated Perforce p4v client. In my case Perforce tried to add moc file to a depo, when I reverted this operation, Perforce removed this moc file from project and deleted it. The file was recreated after the next compilation, but it wasn't included in project, I have to add it manually to Generated files, when I finally understood what was the problem.


I have the same problem, my solution was the encoding( my file with "UTF16LE BOM" can't generate with moc.exe ) , y create another file with ASCII enconding and it work.

HxD HexEditor can help you to see the codification.


I know that this is a very old question, but it seems to be still interesting (I've been here at least 4 or 5 times in the last months) and seems like I found another reason for which is possible to get this error.

In my case in the header file I wrongly typed:

#include "MyClass.h""

Only after inspecting the whole output I found out that at that line the compiler was emitting a warning.

Now that I removed the additional quotation mark my QObject compiles perfectly!


For me, this is the cause: some header or source file not included in QT's project file

참고URL : https://stackoverflow.com/questions/14170770/unresolved-external-symbol-public-virtual-struct-qmetaobject-const-thiscal

반응형