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í:
- ¿Cuál es el efecto de extern "C" en C ++? 13 respuestas
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 ++.