c++ - Símbolo externo sin resolver "public: virtual struct QMetaObject const*__thiscall Parent
qt qobject (19)
Heredé una clase de 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;
}
};
Pero cuando escribo:
Parent ev;
Obtuve el siguiente error:
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)
A diferencia del nombre sugerido, Rebuild Project
no eliminará todo y construirá desde cero. Si recientemente agregó QObject
a su clase, tendrá que ejecutar qmake
nuevamente, por ej.
- Proyecto limpio
- Ejecutar qmake
- Proyecto de construcción
Esto se debe a que, de forma predeterminada, qmake
solo se ejecuta cuando realiza cambios significativos en la solución, como agregar nuevos archivos fuente o modificar el archivo .pro
. Si realiza ediciones en un archivo existente, no sabe si necesita ejecutar qmake
. Sin embargo, cambiar el QObject-ness de una clase definitivamente requiere ejecutar qmake
nuevamente.
Si está extremadamente paranoico, puede eliminar la carpeta Debug
o Release
. Esto definitivamente obligará a Qt a construir todo desde cero.
Agregué archivos cpp / ui a mi proyecto manualmente, pero olvidé agregar el archivo de encabezado explícitamente como archivo de encabezado. Ahora, al compilar, recibí un mensaje de error similar al anterior y los archivos moc _ *. Cpp no se generaron en el directorio de depuración (o versión) de la compilación. Ese no fue un error tan obvio, qmake no se quejó y aparte del mensaje del enlazador no recibí ningún error.
Entonces, si alguien vuelve a encontrarse con el mismo problema (o comete el mismo error de copia y pase): asegúrese de que los archivos de encabezado también se hayan agregado a su archivo de proyecto.
Cualquiera de las respuestas funciona para mí en el entorno VS 2013. Finalmente resuelvo el problema eliminando el proyecto .h / .cpp y volviéndolo a agregar.
Debería eliminar la carpeta de debug
de su aplicación y ejecutarla nuevamente para corregir este problema.
En mi caso (usando QtAdd-in con VS2012 y Qt v4.8.4) ninguna de las sugerencias anteriores funcionó. Por alguna razón, VS no pudo generar archivos moc adecuados (generar resultados: no se encontraron clases relevantes. No se generó salida) y cuando compilé los encabezados relevantes a mano (configurando qt moc como compilador y haciendo clic en ''Compilar'') produjo el archivo moc vacío .
Lo que sí funcionó fue compilar todos los mocs necesarios desde la línea de comandos (moc -o moc_SomeClass.cpp SomeClass.h) y luego reemplazar los incorrectos en la carpeta GeneratedFiles.
Esta es solo una solución (y no es conveniente para un gran proyecto) para que su proyecto se desarrolle con éxito, pero realmente no explica el comportamiento extraño de VS / QtAdd-in.
En mi caso, nada de lo anterior funcionó, pero fue totalmente mi error.
Había anulado las funciones virtuales en el archivo .h (las declaró) pero nunca las había definido en .cpp :)
Entonces, el problema era que necesitaba el compilador Qt MOC para compilar mi archivo .h. Esto se requiere para cualquier clase que extienda QObject o uno de sus hijos. La solución invocada (para mí) al hacer clic derecho en el archivo de encabezado, seleccionar Propiedades y establecer el Tipo de elemento en "Qt MOC Input", luego presionar "Compilar" en el encabezado y luego agregar el archivo moc_myfilename.cpp resultante a mi proyecto.
Esto me sucedió recientemente al cambiar de MingW a MSVC. Tenía una clase / estructura con prototipos listada como clase, y a MingW no le importaba.
MSVC definitivamente ve una diferencia entre class
y struct
cuando se trata de prototipos.
Espero que ayude a alguien más un día.
Estoy trabajando en VS2015 con un cliente Perforce p4v integrado. En mi caso, Perforce intentó agregar un archivo moc a un depósito, cuando revertí esta operación, Perforce eliminó este archivo moc del proyecto y lo eliminó. El archivo se volvió a crear después de la siguiente compilación, pero no se incluyó en el proyecto, tengo que agregarlo manualmente a los archivos generados, cuando finalmente entendí cuál era el problema.
Resolví mi problema agregando esto a mi archivo de encabezado:
#ifndef MYCLASSNAME_H
#define MYCLASSNAME_H
... // all the header file content.
#endif
Si sus archivos moc se generan en el proyecto de estudio visual, intente incluirlos en el proyecto si no están incluidos en el proyecto y luego reconstruir.
Si usa Visual Studio, elimine la línea Q_OBJECT
del archivo de encabezado, guarde el archivo, Q_OBJECT
colocar Q_OBJECT
en el archivo de encabezado y guarde el archivo nuevamente. Esto debería generar el archivo moc_*
y debería construir y vincular correctamente.
Tengo el mismo problema, mi solución fue la codificación (mi archivo con "UTF16LE BOM" no puede generar con moc.exe), y creo otro archivo con código ASCII y funciona.
HxD HexEditor puede ayudarlo a ver la codificación.
Trabajo en VisualStudio solo con un proyecto de C ++ que tiene una interfaz QT. Solo eliminar la línea Q_OBJECT funciona para eliminar los errores del enlazador. Parece que no tiene ningún efecto adverso.
Tuve el mismo problema en Visual Studio y lo resolví siguiendo estos pasos:
- Haga clic derecho en el archivo de encabezado en la solución Explorer
- Propiedades
- Cambiar "Tipo de elemento" a "Herramienta de compilación personalizada"
Luego, en la configuración de Custom Build Tool:
- Ir a General
establece "Línea de Comando" para:
"$ (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_NETWORK_LIB -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"
establecer "Salidas" a:
. / GeneratedFiles / $ (ConfigurationName) / moc _% (Filename) .cpp
establecer "Dependencias Adicionales" a:
$ (QTDIR) / bin / moc.exe;% (FullPath)
Tus valores exactos pueden ser diferentes. Por lo general, se aplican a través de un plugin Qt.
Tuve este problema con Visual Studio 2012 cuando tenía una definición de clase Q_OBJECT en mi archivo cpp. Mover la definición de clase al archivo de encabezado resolvió el problema.
Parece que debería ser posible admitir la clase Q_OBJECT en el archivo cpp agregando el archivo cpp al moc, pero no lo intenté.
Tuve este problema con una "clase privada". Qt usa este modelo a pesar de su código. Realmente me gustó mucho.
Básicamente, tiene una clase privada declarada en una definición de clase de archivo de encabezado público, con un puntero a una instancia de la misma como un miembro de datos de la clase pública. (Nota: es posible que encuentre la vida más fácil para declararlo como una clase de amigos también).
Luego, crea la versión privada de tu clase dentro del archivo cpp para la pública. NO crees un archivo de encabezado para esta clase privada. Haz todo el trabajo sucio con esa clase. Esto oculta toda la implementación de su clase pública, incluidos otros miembros privados.
Sin explicarlo más, este es el punto en lo que se refiere a este hilo. Para hacer que Q_OBJECT funcione, necesitaba agregar esto a la cpp:
#include "MyPublicClass.moc"
El diseño de cpp es así:
- La clase privada está definida
- El moc para la clase pública es #incluido.
- Entonces se define la implementación de clase pública.
Uso CMake para administrar proyectos Qt y el nuevo Q_OBJECT debe agregarse bajo la llamada QT4_WRAP_CPP. Esto generará el moc _ *. Cxx para su inclusión en el proyecto y limpiará los elementos externos no resueltos.
Utilizando QtAdd-in con VS2010 me di cuenta de que los archivos moc _ *. Cpp se actualizaron en la carpeta GeneratedFiles / Debug aunque estaba en modo de lanzamiento. Copiar los archivos en la carpeta de Release funcionó para mí.