Неразрешенный внешний символ " 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)

21 ответов


вы должны удалить debug папка вашего приложения и запустите его снова, чтобы исправить эту проблему.


Если вы используете Visual Studio, удалите строку Q_OBJECT из файла заголовка сохраните файл, поместите Q_OBJECT назад в файл заголовка, сохраните файл снова. Это должно генерировать moc_* файл и должен правильно строить и связывать.


я заметил, что некоторые ответы основаны на Visual Studio.

этот ответ основан на Qt Creator.

в отличие от названия, Rebuild Project не будет уничтожать все и строить с нуля. Если вы недавно добавили QObject (и/или Q_OBJECT) для вашего класса вам придется запустить qmake опять же, например,

  1. Очистить Проект
  2. запустить qmake
  3. Строительство

это потому, что по умолчанию qmake работает только когда вы делаете значительные изменения в своем решении, такие как добавление новых исходных файлов или изменение . Если вы вносите изменения в существующий файл, он не знает, что он должен работать qmake.

как отступление, чтобы заставить Qt строить все с нуля, удалите Debug или .


Итак, проблема заключалась в том, что мне нужен компилятор Qt MOC для компиляции .H-файл. Это необходимо для любых классов, которые расширяют QObject или один из его дочерних элементов. Исправление включало (для меня) щелчок правой кнопкой мыши по заголовочному файлу, выбор свойств и установку типа элемента в "Qt MOC Input", затем нажатие "Compile" в заголовке, а затем добавление результирующего moc_myfilename.cpp файл для моего проекта.


Если ваши MOC-файлы создаются в проекте visual studio, попробуйте включить их в проект, если они не включены в проект, а затем перестроить.


У меня была такая же проблема в Visual Studio, и решил ее следующим образом:

  1. щелкните правой кнопкой мыши файл заголовка в обозревателе решений
  2. свойства
  3. изменить "тип элемента" на "пользовательский инструмент сборки"

затем в пользовательской конфигурации инструмента сборки:

  1. перейти к генералу
  2. установите "Командная строка" в:

    " $(QTDIR)\bin\moc.exe ""%(полный путь) " - o ".\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "" - fStdAfx.h "" - f../../../ src/имя файла.h" -DUNICODE -DWIN32 -DWIN64 -DQT_DLL -DQT_NO_DEBUG -DNDEBUG -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DQT_NETWORK_LIB -DWIN32_LEAN_AND_MEAN -DDIS_VERSION=7 -D_MATH_DEFINES_DEFINED "-И.\SFML_STATIC" "-И.\GeneratedFiles" "И." "-Я$(QTDIR)\включить" "-И.\GeneratedFiles\$(Имяконфигурации).""-Я$(QTDIR)\включать\необходимости некоторые" "-я$(QTDIR)\включать\QtGui пакет" "- I$(QTDIR)\include\QtNetwork"

  3. установите "выходы" в:

    .\GeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp

  4. установите "дополнительные зависимости"в:
    $(QTDIR)\bin\moc.exe;%(полный путь)


ваши точные значения могут быть разными. Они обычно применяются через плагин Qt.


Я использую CMake для управления проектами Qt, и новый Q_OBJECT должен быть добавлен под вызовом QT4_WRAP_CPP. Это создаст moc_*.cxx для включения в проект и очистки неразрешенных внешних объектов.


У меня была эта проблема с Visual Studio 2012, когда у меня было определение класса Q_OBJECT в моем файле cpp. Перемещение определения класса в файл заголовка разрешило проблему.

похоже, что должно быть возможно поддерживать класс Q_OBJECT в файле cpp, добавив файл cpp в moc, но я не пробовал это.


Я добавил файлы cpp/ui в свой проект вручную, но забыл добавить файл заголовка явно как файл заголовка. Теперь при компиляции я получил аналогичное сообщение об ошибке, как указано выше и moc_*.cpp-файлы не были созданы в каталоге отладки (или выпуска) сборки. Это была не такая очевидная ошибка, qmake не жаловался, и кроме сообщения компоновщика я не получил никаких ошибок.

Итак, если кто-то снова столкнется с той же проблемой (или сделает ту же ошибку copy & pase): сделать убедитесь, что файлы заголовков также были добавлены в файл проекта


в моем случае (используя QtAdd-in с VS2012 и Qt v4.8.4) ни одно из вышеперечисленных предложений не сработало. По какой-то причине VS не удалось создать правильные MOC-файлы (вывод сборки: соответствующие классы не найдены. Нет выходных данных.) и когда я скомпилировал соответствующие заголовки вручную (установив qt moc в качестве компилятора и нажав "Compile"), он произвел пустой файл moc.

что действительно работало, так это компиляция всех необходимых MOC из командной строки (moc-o moc_SomeClass.cpp SomeClass.h) и после этого замените неправильное в папке GeneratedFiles.

Это только обходной путь (и не удобный для большого проекта), чтобы ваш проект строился успешно, но на самом деле не объясняет странное поведение VS/QtAdd.


используя QtAdd-in с VS2010, я понял moc_*.файлы cpp были обновлены в папке GeneratedFiles/Debug, хотя я был в режиме выпуска. Копирование файлов в папку Release сработало для меня.


У меня была эта проблема с"частным классом". Qt использует эту модель, хотя их код. Мне самому это очень нравится.

в основном, у вас есть частный объявленный класс в определении класса открытого файла заголовка с указателем на экземпляр его как члена данных открытого класса. (Примечание: Вы можете найти жизнь проще объявить его как класс друга тоже.)

затем создайте закрытую версию своего класса в файле cpp для открытого. Делать Не создавать файл заголовка для этого частного класса. Делать всю грязную работу с этим классом. Это скрывает всю реализацию вашего открытого класса, включая других частных членов.

не объясняя этого далее, вот точка, как она относится к этому потоку. Чтобы получить работу Q_OBJECT, мне нужно было добавить это в cpp:

#include "MyPublicClass.moc"

макет cpp выглядит так:

  1. частный класс определен
  2. moc для общественного класса #включенный.
  3. затем определяется реализация открытого класса.

это случилось со мной недавно при переключении с MingW на MSVC. У меня был прототип класса/структуры, указанный как класс, и MingW не возражал.

MSVC определенно видит разницу между class и struct для прототипирования обеспокоен.

надеюсь, что однажды это поможет кому-то еще.


в моем случае ничего из вышеперечисленного не сработало, но это была полностью моя ошибка.

Я переопределил виртуальные функции .H файл (объявил их), но никогда не определял их .cpp:)


Я решил свою проблему, добавив это в мой файл заголовка:

#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H

... // all the header file content.

#endif

любой ответ работает для меня в среде VS 2013. В конце концов я решаю проблему, удаляя .h/.cpp из проекта и добавить его снова.


Я работаю в VS2015 со встроенным клиентом Perforce p4v. В моем случае волей-неволей попытался добавить MOC-файл в depo, когда я вернул эту операцию, волей-неволей удалил этот MOC-файл из проекта и удалил его. Файл был воссоздан после следующей компиляции, но он не был включен в проект, я должен добавить его вручную в сгенерированные файлы, когда я наконец понял, в чем проблема.


У меня такая же проблема, моим решением была кодировка (мой файл с "UTF16LE BOM" не может генерировать с moc.exe), y создайте еще один файл с ASCII enconding и он работает.

HxD HexEditor может помочь вам увидеть кодификацию.


Я работаю в VisualStudio только с проектом C++, который имеет Qt-интерфейс. Просто удаление строки Q_OBJECT работает штрафы, чтобы удалить ошибки компоновщика. Кажется, не имеет никакого отрицательного эффекта.


Я знаю, что это очень старый вопрос, но, похоже, он все еще интересен (я был здесь, по крайней мере, 4 или 5 раз за последние месяцы) и, похоже, я нашел еще одну причину, по которой можно получить эту ошибку.

в моем случае в заголовочном файле я неправильно набрал:

#include "MyClass.h""

только после проверки всего вывода я обнаружил, что в этой строке компилятор выдает предупреждение.

теперь, когда я удалил дополнительную кавычку моего QObject компилирует отлично!


для меня это причина: некоторый заголовок или исходный файл, не включенный в файл проекта QT