2009-07-01 18 views
21

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 está bien. Sin embargo, si cambio el nombre del archivo a .cpp (haciendo cosas simples que funcionan tanto en c/C++) obtengo una referencia no definida. Estos son pequeños programas simples que escribo para fines de prueba, por lo que no hay cosas sofisticadas. Compilo usando:C-library sin vincular usando gcc/g ++

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++ 

resultados en referencia indefinida a cualquier función en customlibrary.lib. Intenté crear un enlace simbólico llamado customlibrary.a pero sin suerte.

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

Respuesta

37

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

Supongo que su biblioteca tiene un archivo de inclusión que declara su interfaz pública. Para que sea compatible tanto con C como con C++, debe disponer decirle a un compilador de C++ que debe suponerse que las funciones que declara utilizan el enlace y la denominación de C.

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

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

en su main.cpp en lugar de simplemente incluyendo customlibrary.h directamente.

Para hacer la cabecera obra misma en ambos idiomas y correcta declaran sus funciones como C-como en C++, ponga la siguiente cerca de la parte superior del archivo de cabecera:

#ifdef __cplusplus 
extern "C" { 
#endif 

y la siguiente en la parte inferior:

#ifdef __cplusplus 
} 
#endif 
+1

el símbolo '__cplusplus' tiene dos guiones bajos, como se define por los estándares relevantes. – RBerteig

2

¿tiene su archivo de cabecera tienen la costumbre

#ifdef __cplusplus 
extern "C" { 
#endif 

// ... 

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

para dar la li Brary funciones C vinculación explícitamente.

Los archivos .cpp se compilan con enlaces C++, es decir, el nombre de la creación de cambios por defecto.

4

El compilador de C++ realiza lo que se conoce como mangle de nombres: los nombres que aparecen en el código no son los mismos que los del vinculador. La forma normal de alrededor de esto es decirle al compilador que ciertas funciones necesitan vinculación C:

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

o lo haga por un archivo de cabecera conjunto:

// myfile.cpp 
extern "C" { 
    #include "mylibdefs.h"  // defs for your C library functions 
} 
Cuestiones relacionadas