setup oxygen instalar for compiler compile cdt c++ linker g++ eclipse-cdt

c++ - oxygen - use eclipse for c



Errores del vinculador C++ de GCC: referencia no definida a ''vtable para XXX'', referencia no definida a ''ClassName:: ClassName()'' (12)

El problema para mí resultó ser bastante oscuro. Mi clase se veía así:

//----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() { } virtual int foo() { return 0; } } //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" //----------------------------------------- //----------------------------------------- // main.h class derived : public base { public: virtual int foo() ; } //----------------------------------------- //----------------------------------------- // main.cpp int main () { derived d; } //-----------------------------------------

El problema está en el enlazador. Mi archivo de encabezado entró en una biblioteca en alguna parte, pero todas las funciones virtuales se declararon ''en línea'' en la declaración de clase. Como no existía un código que utilizara las funciones virtuales (aún), el compilador o el vinculador omitieron poner los cuerpos funcionales reales en su lugar. Tampoco se pudo crear el vtable.

En mi código principal, de donde derivaba de esta clase, el enlazador intentó conectar mi clase a la clase base y a su vtable. Pero el vtable había sido descartado.

La solución fue declarar al menos uno de los cuerpos de las funciones virtuales fuera de la declaración de clase, así:

//----------------------------------------- // libbase.h class base { public: base() { } virtual ~base() ; //-- No longer declared ''inline'' virtual int foo() { return 0; } } //----------------------------------------- //----------------------------------------- // libbase.cpp #include "libbase.h" base::~base() { } //-----------------------------------------

Estoy configurando un proyecto de C ++, en Ubuntu x64, usando Eclipse-CDT. Básicamente estoy haciendo un mundo de saludo y enlazando a una biblioteca comercial de terceros.

He incluido los archivos de encabezado, vinculados a sus bibliotecas, pero todavía tengo errores de enlazador. ¿Hay algunos posibles problemas aquí que no sean los obvios (por ejemplo, estoy 99% seguro de estar enlazando a la biblioteca correcta).

  1. ¿Hay alguna manera de confirmar que las bibliotecas estáticas a las que estoy enlazando son de 64 bits?
  2. ¿Hay alguna forma de confirmar que la biblioteca tiene la clase (y los métodos) que espero que tenga?

Eclipse dice:

Building target: LinkProblem Invoking: GCC C++ Linker g++ -L/home/notroot/workspace/somelib-3/somelib/target/bin -o"LinkProblem" ./src/LinkProblem.o -lsomelib1 -lpthread -lsomelib2 -lsomelib3 ./src/LinkProblem.o: In function `main'': /home/notroot/workspace/LinkProblem/Debug/../src/LinkProblem.cpp:17: undefined reference to `SomeClass::close()'' ./src/LinkProblem.o: In function `SomeOtherClass'': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `SomeClass::SomeClass()'' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:148: undefined reference to `vtable for SomeOtherClass'' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:151: undefined reference to `SomeClass::~SomeClass()'' ./src/LinkProblem.o: In function `~SomeOtherClass'': /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `vtable for SomeOtherClass'' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'' /home/notroot/workspace/somelib-3/somelib/include/sql/somefile.h:140: undefined reference to `SomeClass::~SomeClass()'' collect2: ld returned 1 exit status make: *** [LinkProblem] Error 1


En cuanto a los problemas con Qt4, no pude usar la opción qmake moc mencionada anteriormente. Pero ese no era el problema de todos modos. Tenía el siguiente código en la definición de clase:

class ScreenWidget : public QGLWidget { Q_OBJECT // must include this if you use Qt signals/slots ... };

Tuve que eliminar la línea "Q_OBJECT" porque no tenía señales ni ranuras definidas.


En mi caso, el problema ocurrió cuando olvidé agregar el = 0 en una función en mi clase virtual pura. Se corrigió cuando se agregó = 0. Lo mismo que para Frank arriba.

class ISettings { public: virtual ~ISettings() {}; virtual void OKFunction() =0; virtual void ProblemFunction(); // missing =0 }; class Settings : ISettings { virtual ~Settings() {}; void OKFunction(); void ProblemFunction(); }; void Settings::OKFunction() { //stuff } void Settings::ProblemFunction() { //stuff }


Este error de enlazador generalmente (en mi experiencia) significa que ha anulado una función virtual en una clase secundaria con una declaración, pero no ha dado una definición para el método. Por ejemplo:

class Base { virtual void f() = 0; } class Derived : public Base { void f(); }

Pero no has dado la definición de f. Cuando usas la clase, obtienes el error del enlazador. Al igual que un error de enlazador normal, es porque el compilador sabía de lo que estaba hablando, pero el enlazador no pudo encontrar la definición. Simplemente tiene un mensaje muy difícil de entender.


Este error también ocurrirá cuando simplemente declaremos una función virtual sin ninguna definición en la clase base.

Por ejemplo:

class Base { virtual void method1(); // throws undefined reference error. }

Cambie la declaración anterior a la siguiente, funcionará bien.

class Base { virtual void method1() { } }


Me encontré con el problema ahora, también. La aplicación definía una clase de interfaz virtual pura y se suponía que una clase definida por el usuario proporcionada a través de una biblioteca compartida implementaba la interfaz. Al vincular la aplicación, el vinculador se quejó de que la biblioteca compartida no proporcionaría vtable y type_info para la clase base, ni podría encontrarse en ningún otro lado. Resultó que simplemente olvidé hacer uno de los métodos de la interfaz puramente virtuales (es decir, omití el "= 0" al final de la declaración. Muy rudimentario, aún así es fácil pasar por alto y desconcertante si no se puede conectar el diagnóstico del enlazador al causa principal.


Puse esto para los visitantes futuros:

si está recibiendo el error al crear un objeto Exception , la causa probablemente sea una falta de definición para what() función virtual.


Qt C ++ mostrará este error cuando cambie una clase de modo que ahora herede de QObject (es decir, para que ahora pueda usar señales / ranuras). Al ejecutar qmake -r, se llamará a moc y se solucionará este problema.

Si está trabajando con otros a través de algún tipo de control de versión, querrá hacer algunos cambios en su archivo .pro (es decir, agregar / eliminar una línea en blanco). Cuando todos los demás reciban los cambios y ejecuten make, make verán que el archivo .pro ha cambiado y se ejecutará automáticamente qmake. Esto evitará que tus compañeros repitan tu frustración.


Si tiene una clase base con función virtual pura, asegúrese de que el constructor y el destructor de su clase base tengan cuerpo, de lo contrario el enlazador falla.


Suponiendo que esos métodos están en una de las libs, parece un problema de pedido.

Al vincular bibliotecas en un archivo ejecutable, se realizan en el orden en que se declaran.
Además, el vinculador solo tomará los métodos / funciones requeridos para resolver las dependencias actualmente pendientes. Si una biblioteca posterior utiliza métodos / funciones que originalmente no eran requeridos por los objetos, faltarán dependencias.

Cómo funciona:

  • Tome todos los archivos de objeto y combínelos en un ejecutable
  • Resuelva cualquier dependencia entre los archivos de objeto.
  • Para cada biblioteca en orden:
    • Verifique las dependencias no resueltas y vea si la lib las resuelve.
    • Si es así, cargue la parte requerida en el ejecutable.

Ejemplo:

Objetos requiere:

  • Abierto
  • Cerca
  • BatchRead
  • BatchWrite

Lib 1 proporciona:

  • Abierto
  • Cerca
  • leer
  • escribir

Lib 2 proporciona

  • BatchRead (pero usa lib1: leer)
  • BatchWrite (pero usa lib1: write)

Si está vinculado así:

gcc -o plop plop.o -l1 -l2

Entonces el enlazador no podrá resolver los símbolos de lectura y escritura.

Pero si enlace la aplicación de esta manera:

gcc -o plop plop.o -l2 -l1

Entonces se vinculará correctamente. Como l2 resuelve las dependencias BatchRead y BatchWrite, pero también agrega dos nuevas (lectura y escritura). Cuando nos vinculamos con l1, las cuatro dependencias se resuelven.


Tuve este mensaje de error cuando probaba "hello world" como cosas con Qt. Los problemas desaparecieron ejecutando correctamente el qt moc (compilador de metaobjetos) y compilando + incluyendo estos archivos generados por moc correctamente.


Tuve este mensaje de error. El problema fue que declare un destructor virtual en el archivo de encabezado, pero el cuerpo de las funciones virtuales en realidad no se implementó.