2010-09-16 18 views

Respuesta

9

Es necesario cuando se debe llamar a una función C++ por el código C en lugar del código C++.

Básicamente, cuando desee que su biblioteca C++ sea compatible con versiones anteriores.

+2

No, no, no ... ugh! Si un proyecto es 'C', no le agregue' C++ ': conviértalo en' C++ 'y, si es necesario, agregue' C' al proyecto 'C++'. * O (incluso mejor en mi humilde opinión) mantenlo en 'C' y evita' C++ 'por completo. * – pmg

+2

Esta respuesta es correcta pero incompleta, como la respuesta de @Graham Perks, que también es correcta pero incompleta. La respuesta completa sería la suma de ambos. –

+0

@pmg: puede que no sea el propietario del Proyecto C o no pueda cambiar la interfaz que desean, incluso si su biblioteca está desarrollada en C++ –

13

Si su función está implementada en un archivo .c, los archivos .cpp necesitarán la referencia externa "C", o bien harían referencia a un nombre de función de estilo C++ y el enlace fallaría.

También es útil para exportar funciones desde archivos DLL para que se exporten con un nombre no destruido.

+3

Esta respuesta es correcta pero incompleta, como la respuesta de @Randolpho, que también es correcta pero incompleta. La respuesta completa sería la suma de ambos. –

3

Debido a que las firmas de funciones generadas por los compiladores C y C++ difieren - esto configura la convención C para la función C incluso cuando se usa C++.

4

Como sabe, la función de sobrecarga de función de C++, que define la misma función o método muchas veces con diferentes parámetros. Para ello, el compilador tiene que añadir un poco de parte de los símbolos para cada uno ... por ejemplo, el compilador va a cambiar el nombre de la función foo en la siguiente declaración de

void foo(int f,char c); 

a

[email protected]&c 

Desafortunadamente, C no es compatible con esto. Todos los nombres de funciones permanecen iguales después de compilarlo. Entonces, para llamar a una función C++ desde c, debe saber el nombre exacto después de la modificación y creo que es difícil y diferente de un compilador a otro.

Para evitar esto y poder llamada C++ c función de parada y el compilador de cambio de los nombres que tienen que utilizar esta palabra clave como

extern "C" { 
void foo(int f,char c); 
} 

eso es todo !!!

+0

+1 Para explicar claramente las razones, pero esto también ocurre en la dirección opuesta: si tiene una función en C en una biblioteca e incluye el encabezado sin el calificador 'extern 'C" ', el compilador de C++ destruirá el símbolo. Luego, en la etapa de enlace, intentará localizar el símbolo mutilado y no lo hará, ya que el compilador c no modificó el nombre al compilar el código C. –

9

Existen dos usos bastante diferentes para extern "C". Una es definir una función en C++ que debería llamar a desde C. Es decir, está escribiendo código en C++, pero necesita interconectarse con el código C. En este caso, definir la función como extern "C":

extern "C" { 
    int c_callable_func1() {} 
    int c_callable_func2() {} 
} 

Al hacer esto, la interfaz de esas funciones debe seguir más o menos las mismas reglas que lo harían en C, así (por ejemplo, se puede' sobrecargar las funciones o usar valores predeterminados para cualquier parámetro).

La otra situación (considerablemente más común) es que tiene un código escrito en C al que desea llamar desde C++. En este caso, las definiciones de la función permanecen exactamente como antes, pero las funciones deben declararse/prototipadas como extern "C".En un caso típico, que desea utilizar una única cabecera que puede ser #include d en cualquier C o archivo C++, por lo que la estructura es como la siguiente:

// myheader.h 
#ifndef MY_HEADER_H_INCLUDED_ 
#define MY_HEADER_H_INCLUDED_ 

#ifdef __cplusplus 
extern "C" { 
#endif 

    int func1(void); 
    void func2(int); 

#ifdef __cplusplus 
} 
#endif 

#endif 

Así, un compilador de C++ ver las declaraciones de función (y typedef s, etc.) rodeado por un bloque extern "C", mientras que un compilador C verá prototipos, no rodeado por algo que no reconoce.

En el primer caso (funciones C++ llamables desde C), normalmente estructurará el encabezado aproximadamente de la misma manera, por lo que también puede llamar esas funciones desde C++ si es necesario (pero en la interfaz, aún pierde todo características de C++ como la sobrecarga de funciones).