tipos sirve que para lenguaje funciones ejemplos datos caracteristicas c++ static-libraries

lenguaje - para que sirve c++



referencias no definidas de c++ con biblioteca estática (5)

Este es probablemente un problema de orden de enlace. Cuando el enlazador GNU ve una biblioteca, descarta todos los símbolos que no necesita. En este caso, su biblioteca aparece antes que su archivo .cpp, por lo que la biblioteca se descarta antes de compilar el archivo .cpp. Hacer esto:

g++ -o main.exe main.cpp -L. -lmylib

o

g++ -o main.exe main.cpp myClass.lib

El vinculador de Microsoft no tiene en cuenta el orden de las bibliotecas en la línea de comandos.

Intento crear una biblioteca estática de una clase, pero cuando trato de usarla, siempre obtengo errores con referencias indefinidas en cualquier cosa. La forma en que procedí fue crear el archivo objeto como

g++ -c myClass.cpp -o myClass.o

y luego empacarlo con

ar rcs myClass.lib myClass.o

Hay algo que obviamente me extraño en general con esto. Apuesto a que es algo con símbolos. Gracias por cualquier consejo, sé que probablemente sea algo que podría averiguar si leo algún tutorial, lo siento si me molesto con cosas estúpidas :)

editar:

myClass.h:

class myClass{ public: myClass(); void function(); };

myClass.cpp:

#include "myClass.h" myClass::myClass(){} void myClass::function(){}

programa usando la clase:

#include "myClass.h" int main(){ myClass mc; mc.function(); return 0; }

finalmente lo compilo así:

g++ -o main.exe -L. -l myClass main.cpp

el error es simplemente clásico:

C:/Users/RULERO~1/AppData/Local/Temp/ccwM3vLy.o:main.cpp:(.text+0x31): undefined reference to `myClass::myClass()'' C:/Users/RULERO~1/AppData/Local/Temp/ccwM3vLy.o:main.cpp:(.text+0x3c): undefined reference to `myClass::function()'' collect2: ld returned 1 exit status


Este es un problema sobre cómo el enlazador optimiza el código de salida. Supongamos que tenemos un ejecutable que usa dos bibliotecas: Lib_A y Lib_B . Lib_A depende de Lib_B Lib_A define símbolos: Lib_A1 y Lib_A2 , y Lib_B define el símbolo Lib_B1 y Lib_B2 . Ahora supongamos que el ejecutable usa solo el símbolo Lib_A1 , y Lib_A1 usa el símbolo Lib_B1 que se define en Lib_B . El símbolo Lib_B1 nunca se usa en el ejecutable.

  1. En el caso de Windows, el enlazador funciona de la siguiente manera: Tengo un ejecutable con dos que usa algunas libs y todos los símbolos utilizados en ejecutable y todas las libs son lib_A1 y lib_B1 . Por lo tanto, necesitaré estos dos símbolos, y el resto es innecesario. Voy a undefine lib_A2 y lib_B2
  2. En el caso de Linux, si vincula Lib_B antes que Lib_A, haga lo siguiente: g++ .... -lLib_B -lLib_A El enlazador funciona de la siguiente manera: Tengo el ejecutable que primero vincula a Lib_B . No veo que el ejecutable use el símbolo Lib_B1 ni Lib_B2 . Son innecesarios, por lo tanto, los definiré indefinidamente. Más tarde, el vinculador ver. Oh, tengo otra biblioteca Lib_A . Puedo ver que el ejecutable usa el símbolo Lib_B1 . Lo mantendré y definiré el símbolo no utilizado Lib_B2 . No ve que Lib_B1 usa Lib_A1 , que ya está indefinido.
  3. En el caso de Linux, si vincula Lib_A antes de Lib_B, haga lo siguiente: g++ ... -lLib_A -lLib_B El enlazador funciona de la siguiente manera: Tengo el ejecutable que primero vincula a Lib_A . Oh, puedo ver que el ejecutable usa Lib_A1 . Los guardaré y definiré Lib_A2 . Más tarde puede ver. Oh, tengo otra biblioteca Lib_B . Puedo ver que ahora ejecutable con símbolos ya vinculados, usa Lib_B1 , los guardaré. Como resultado, mantiene Lib_B1 y Lib_A1 , y Lib_B2 y Lib_A2 no definidos .

Esto debería evitar el enlace de errores y crear la biblioteca compartida .so:

LOCAL_ALLOW_UNDEFINED_SYMBOLS := true


Otra posible causa: olvidar el extern "C" .

Me encontré con esto porque estaba tratando de vincular un programa C ++ con una biblioteca C estática. El encabezado de la biblioteca no tenía una extern "C" por lo que el vinculador buscaba un nombre de función mutilado, y la biblioteca en realidad tenía el nombre de la función no protegida.

Me tomó un tiempo descubrir qué estaba pasando, así que espero que esto ayude a otra persona.


Utilizar:

g++ -o main.exe main.cpp myClass.lib

El uso de la ruta de la biblioteca y el indicador -l está lleno de problemas, pero si debe hacerlo, cambie el nombre de su biblioteca a libmylib.a y compílelo como sigue:

g++ -o main.exe main.cpp -L. -lmylib

Tenga en cuenta también que, por razones de portabilidad, generalmente es una mala idea usar mayúsculas y minúsculas en los nombres de los archivos de origen o de salida.