2011-03-30 13 views
6

Ahora tengo un problema bastante confuso para mí: Tengo un programa escrito en C++ y enlaces contra una biblioteca en C. Incluyo las clases de encabezado usando el habitualLa optimización de GCC da como resultado un "símbolo indefinido" en el tiempo de ejecución

extern "C" { 
    #include <libheader.h> 
} 

Todo funciona bien siempre que no utilice la optimización de gcc. Una vez que enciendo even -O1, así el primer nivel de optimización, durante el tiempo de ejecución obtengo un error de "símbolo indefinido" para un símbolo de esta biblioteca. Sin embargo, el nombre ha pasado por el cambio de nombre que debe deshabilitarse debido a extern "C".

La función que llama al símbolo en cuestión está en línea, en caso de que esto importe. El compilador utilizado es gcc 4.4.3.

Honestamente, ni siquiera tengo una idea de qué buscar, así que estaría muy agradecido si alguno de ustedes pudiera darme alguna razón para este comportamiento.

Gracias por su apoyo.

+0

¿Se puede eliminar la línea (es decir, hacer que la función no esté en línea) y ver si comienza a funcionar? – sashoalm

+1

Como alternativa a la sugerencia de @ satuon, ¿podría hacer que la función en línea llame a una función C++ que envuelva la función C y vea si eso la hace empezar a funcionar? –

+0

Gracias por su respuesta! Probé ambas sugerencias, sin embargo, el símbolo aún no se encuentra. – Thilo

Respuesta

1

¿Es posible que la cabecera que define la función en línea de llamada incluye la cabecera de la biblioteca sin extern "C" la envoltura, y en todas partes se utilizan las líneas de envoltura?

¿Has probado otros niveles como -O2?

¿Intentó deslindar su función?

+0

Gracias por las ideas. Sí, el encabezado del archivo correcto ciertamente usa el contenedor 'extern 'C" '. -O2 y -O3 tienen el mismo efecto. Como se indicó anteriormente, eliminar el en línea tampoco ayuda. – Thilo

+0

@Thilo Específicamente, ¿eliminó la función AND en línea y movió la función desde el encabezado a un archivo fuente para que el compilador no pueda decidir alinearlo automáticamente? –

+0

Argh ... Gracias por aclarar. Se olvidó de mover la función previamente inscrita a un archivo fuente. Esto resuelve el problema. Sin embargo, el resultado no es realmente elegante, ya que tener la función en línea podría ser significativamente más rápido. – Thilo

3

Si tiene una función definida cuando no está en línea pero no está definida cuando está en línea, entonces el problema debería ser bastante simple de definir.

Ha utilizado la función en algún lugar sin incluir su archivo de encabezado.

Revise todos los archivos que llaman a esta función y asegúrese de que el encabezado esté incluido.

0

Enrollar un encabezado C con extern "C" {...} no siempre funciona; en general, los encabezados deben estar diseñados para funcionar con ambos idiomas para que trabajen con ambos idiomas.

En este caso, sin más detalles, es difícil decir exactamente lo que está sucediendo , pero la palabra clave inline significa cosas diferentes en C y C++ en ; No esperaría que un encabezado con las funciones inline funcione de esta manera . (A mano, no esperaría los síntomas que está recibiendo, pero tampoco me sorprenden )

La forma correcta de manejar esto es insistir que el proveedor de la biblioteca proporcione un encabezado que está diseñado para funcionar en ambos idiomas.

De no ser así, la forma correcta de manejar esto es para escribir su propio código C, que incluye la cabecera y envuelve todas las funciones que necesidad, y para escribir su propia cabecera para este código C, que está diseñado a se incluirán desde ambos idiomas. Que es, lo admito, mucho trabajo; obtener el proveedor para hacer su trabajo, en lugar de tener que hacer la mitad para él.

4

Usted dice que está incluyendo el archivo libheader.h en un bloque extern "C", pero que el símbolo que el enlazador está buscando ha sido desmenuzado.

Eso es una indicación de que libheader.h también está siendo incluido exterior del bloque extern "C" (la incluyen dentro del bloque extern "C" es probablemente una nop debido a incluir guardias en libheader.h).

Busque otras formas en que libheader.h se pueden incluir. El -E de GCC y/o las diversas opciones -M pueden o no ayudar con esto. O (aunque sólo sea por una prueba) mover el bloque extern "C" dentro libheader.h:

// at start of libheader.h: 
#ifdef __cplusplus 
extern "C" { 
#endif 

/* existing contents of libheader.h */ 
// ... 

// at end of libheader.h: 
#ifdef __cplusplus 
} 
#endif 

Tenga en cuenta que las especificaciones de vinculación pueden anidar, por lo que no tiene que quitar los extern "C" bloques existentes en los sitios #include.

No sé por qué el problema sucedería solo para compilaciones optimizadas, excepto que tal vez el archivo .c o .cpp que contiene la versión no en línea de la función de llamada obtiene los encabezados correctos, y solo necesita ser una unidad de traducción que obtiene los encabezados incorrectos e indica la función de llamada para ver el problema.

+0

¡Gracias! Esa podría ser una buena idea para rastrear el problema, si ese es el motivo. Tristemente, solo tendré tiempo de analizarlo la semana que viene el viernes, informaré en ese momento. – Thilo

Cuestiones relacionadas