from example ejemplo c++ c extern-c

c++ - example - extern function c



¿Cuándo usar extern "C" en palabras simples? (7)

Las funciones de C ++ están sujetas a la manipulación de nombres . Esto hace que sea imposible llamar directamente desde el código C a menos que se use extern "C" .

Esta pregunta ya tiene una respuesta aquí:

Quizás no entiendo las diferencias entre C y C ++, pero cuándo y por qué necesitamos usar

extern "C" {

? Aparentemente es una "convención de vinculación".

Lo leí brevemente y noté que todos los archivos de encabezado .h incluidos con MSVS rodean su código con él. ¿Qué tipo de código es exactamente el "código C" y NO el "código C ++"? Pensé que C ++ incluía todo el código C?

Supongo que este no es el caso y que C ++ es diferente y que las características / funciones estándar existen en uno u otro pero no en ambos (es decir: printf es C y cout es C ++), pero que C ++ es compatible con versiones anteriores, aunque Declaración externa "C". ¿Es esto correcto?

Mi siguiente pregunta depende de la respuesta a la primera, pero la preguntaré aquí de todos modos: Como los archivos de encabezado de MSVS que están escritos en C están rodeados por una "C" {...} externa, ¿cuándo necesitaría usar esto? usted mismo en su propio código? Si su código es código C y está intentando compilarlo en un compilador de C ++, ¿no debería funcionar sin problemas porque todos los archivos h estándar que incluye ya tendrán la parte externa "C" con el compilador de C ++?

¿Tienes que usar esto al compilar en C ++ pero enlazar a bibliotecas C ya construidas o algo así?


Las otras respuestas son correctas, pero un ejemplo completo de "caldera" probablemente ayude. El método canónico para incluir el código C en proyectos C y / o C ++ es el siguiente:

// // C_library.h // #ifdef __cplusplus extern "C" { #endif // // ... prototypes for C_library go here ... // #ifdef __cplusplus } #endif

-

// // C_library.c // #include "C_library.h" // // ... implementations for C_library go here ... //

-

// // C++_code.cpp // #include "C_library.h" #include "C++_code.h" // // ... C++_code implementation here may call C functions in C_library.c ... //

Nota: lo anterior también se aplica a las llamadas a código C desde Objective-C ++.


Los compiladores de C ++ modifican los nombres en su tabla de símbolos de manera diferente a los compiladores de C. extern "C" usar la declaración extern "C" para decirle al compilador de C ++ que use la convención de manipulación de C en lugar de construir la tabla de símbolos.


Uso ''extern c'' para que C # pueda leer mi código de C ++ sin tener que averiguar el nombre extra que se hace al exportar una función dll de C ++. De lo contrario, hay caracteres adicionales sin sentido (o realmente, no en inglés) que tengo que agregar al final de un punto de entrada de función en el lado C # para poder acceder correctamente a una función de C ++ en una dll.


extern "C" {} bloques extern "C" {} dicen a un compilador de C ++ que use las convenciones de nomenclatura y llamada de C. Si no usas esto, obtendrás errores de vinculador si intentas incluir una biblioteca de C con tu proyecto de C ++ porque C ++ modificará los nombres. Tiendo a usar esto en todos mis encabezados de C en caso de que alguna vez se usen en un proyecto de C ++:

#ifdef __cplusplus extern "C" { #endif /* My library header */ #ifdef __cplusplus } // extern #endif


extern "C" usar extern "C" en C ++ al declarar una función que se implementó / compiló en C. El uso de extern "C" le dice al compilador / vinculador que use las convenciones de nomenclatura y llamada de C, en lugar de la manipulación de nombres en C ++ y Convenciones de llamada de C ++ que se utilizarían de otro modo. Para las funciones proporcionadas por otras bibliotecas, casi nunca necesitará usar extern "C" , ya que las bibliotecas bien escritas ya tendrán esto allí para las API públicas que exporta a C y C ++. Sin embargo, si escribe una biblioteca que desea que esté disponible tanto en C como en C ++, entonces tendrá que poner eso de forma condicional en sus encabezados.

En cuanto a si todo el código C es código C ++ ... no, eso no es correcto. Es un mito popular que C ++ es un "superconjunto de C". Si bien C ++ se esfuerza por ser lo más compatible posible con C, existen algunas incompatibilities . Por ejemplo, bool es válido en C ++ pero no válido en C, mientras que _Bool existe en C99, pero no está disponible en C ++.

En cuanto a si alguna vez necesitará usar la "C" externa con los archivos ".h" del sistema ... cualquier implementación bien diseñada tendrá a su disposición aquellas para que no tenga que usarlas. Sin embargo, para asegurarse de que se proporcionen, debe incluir el archivo de encabezado equivalente que comienza con "c" y omite ".h". Por ejemplo, si incluye <ctype.h>, a casi cualquier sistema razonable se le agregará la "C" externa; sin embargo, para tener la seguridad de un encabezado compatible con C ++, debe incluir el encabezado <cctype>.

También puede interesarle mezclar C y C ++ de C ++ FAQ Lite .


extern "C" utilizar extern "C" cuando desee utilizar la convención de llamada de C en el código compilado por un compilador de C ++. Hay dos razones para esto:

  • Tiene una función implementada en C y desea llamarla desde C ++.

  • Tiene una función implementada en C ++ y desea llamarla desde C. Tenga en cuenta que en este caso solo puede usar la parte C de C ++ en la interfaz de la función (sin clases, ...).

Aparte de C, esto también se aplica cuando se desea interoperar entre C ++ y otros idiomas que utilizan las mismas convenciones de llamada y nomenclatura que C.

Normalmente, las declaraciones en un archivo de encabezado C están rodeadas por

#ifdef __cplusplus extern "C" { #endif [... C declarations ...] #ifdef __cplusplus } #endif

para que sea utilizable desde C ++.