C-library no enlaza usando gcc / g++


Tengo una biblioteca c que uso en gcc. La biblioteca tiene la extensión .lib, pero siempre está vinculada como una biblioteca estática. Si escribo un programa que usa la biblioteca como código c, todo como a-ok. Sin embargo, si cambio el nombre del archivo a .cpp (haciendo cosas simples que funcionan tanto en c / c++) obtengo una referencia indefinida. Estos son pequeños programas simples que escribo con fines de prueba, así que no hay cosas elegantes. Compilo usando:

gcc -g -Wall -I <path to custom headers> -o program main.c customlibrary.lib -lm -lpthread

Lo anterior funciona como un encanto. Sin embargo:

g++ -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread

O

gcc -g -Wall -I <path to custom headers> -o program main.cpp customlibrary.lib -lm -lpthread -lstdc++

Resulta en una referencia indefinida a cualquier función en customlibrary.lib. Intenté crear un enlace simbólico llamado customlibrary.pero no hubo suerte.

¿Por qué g++ no encuentra reconocer mi biblioteca? Desafortunadamente no tengo acceso al código fuente de las bibliotecas, pero vincular una c-lib a c++ no debería ser un problema, ¿verdad?

Author: Cœur, 2009-07-01

3 answers

Su biblioteca parece tener una API que asume que se llamará desde C, no desde C++. Esto es importante porque C++ requiere efectivamente que los símbolos exportados de una biblioteca tengan más información que solo el nombre de la función. Esto es manejado por "name mangling" las funciones.

Asumo que su biblioteca tiene un archivo include que declara su interfaz pública. Para que sea compatible tanto con C como con C++, debe hacer arreglos para decirle a un compilador de C++ que las funciones que declara se debe suponer que utiliza la vinculación y el nombramiento de C.

Una respuesta fácil para probar esto es hacer esto:

extern "C" {
#include "customlibrary.h"
}

En su principal.cpp en lugar de solo incluir customlibrary.h directamente.

Para hacer que el encabezado en sí funcione en ambos lenguajes y declare correctamente sus funciones como C-like a C++, coloque lo siguiente cerca de la parte superior del archivo de encabezado:

#ifdef __cplusplus
extern "C" {
#endif

Y lo siguiente cerca de la parte inferior:

#ifdef __cplusplus
}
#endif
 38
Author: RBerteig,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-01 09:23:25

El compilador de C++ realiza lo que se conoce como alteración de nombres: los nombres que aparecen en su código no son los mismos que ve su enlazador. La forma normal de hacer esto es decirle al compilador que ciertas funciones necesitan un enlace C:

// myfile.cpp
extern "C" int libfun();    // C function in your library

O hacerlo para un archivo de encabezado completo:

// myfile.cpp
extern "C" {
  #include "mylibdefs.h"      // defs for your C library functions
}
 4
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-01 09:26:41

¿Su archivo de encabezado tiene el

#ifdef __cplusplus
extern "C" {
#endif

// ...

#ifdef __cplusplus
} /* extern "C" */
#endif

Para dar a la biblioteca funciones C enlace explícitamente.

.los archivos cpp se compilan con el enlace C++, es decir, el mangling de nombres por defecto.

 2
Author: laalto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-01 09:23:34