Tengo una biblioteca C ++ que proporciona varias clases para administrar datos. Tengo el código fuente de la biblioteca.
Quiero extender la API de C ++ para admitir llamadas a funciones de C para que la biblioteca se pueda usar con código C y código C ++ al mismo tiempo.
Estoy usando la cadena de herramientas GNU (gcc, glibc, etc.), por lo que el soporte de lenguaje y arquitectura no es un problema.
¿Hay alguna razón por la que esto no sea técnicamente posible?
¿Hay alguna trampa de la que deba tener cuidado?
¿Hay recursos, código de ejemplo y / o documentación disponible al respecto?
Algunas otras cosas que he descubierto:
- Utilice lo siguiente para ajustar los encabezados de C ++ que deben utilizar el código C.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
- Mantenga las interfaces C ++ "reales" en archivos de encabezado separados que no estén incluidos en el principio C. Piense en PIMPL aquí. Usar
#ifndef __cplusplus #error
cosas ayuda aquí a detectar cualquier locura. - Cuidado con los identificadores de C ++ como nombres en código C
- Enumeraciones que varían en tamaño entre los compiladores de C y C ++. Probablemente no sea un problema si está utilizando la cadena de herramientas GNU, pero aún así, tenga cuidado.
Para estructuras, siga el siguiente formulario para que C no se confunda.
typedef struct X { ... } X
Luego use punteros para pasar objetos de C ++, solo deben declararse en C como estructura X donde X es el objeto de C ++.
Todo esto es cortesía de un amigo que es un mago en C ++.
Respuestas:
Sí, esto es ciertamente posible. Necesitará escribir una capa de interfaz en C ++ que declare funciones con
extern "C"
:Luego, llamará
foo()
desde su módulo C, que pasará la llamada a larealFoo()
función que está implementada en C ++.Si necesita exponer una clase C ++ completa con miembros de datos y métodos, entonces puede que necesite hacer más trabajo que este simple ejemplo de función.
fuente
extern "C"
colocarse solo en declaraciones (y no en definiciones)? Porque mencionaste "la capa que declara funciones", pero tu código de muestra también es una definición. En otras palabras, ¿deberíamos colocarlo en archivos de encabezado o archivos de origen? (¿O ambos?)extern "C"
allí. Su compilador le dirá si también debe incluirlo en la definición.C ++ FAQ Lite: "Cómo mezclar código C y C ++" .
Algunas trampas se describen en las respuestas a estas preguntas:
fuente
Problema principal: las excepciones no se pueden detectar en C. Si existe la posibilidad de que surja una excepción en el código C ++, escriba su código C o sus envoltorios C ++ con mucho cuidado. Por el contrario, los mecanismos de excepción (es decir, longjump) en el código C (como se encuentran en varios lenguajes de programación) no son necesarios para invocar destructores para objetos C ++ en la pila.
fuente
puede mezclar código C / C ++. Si su función main () está en C ++, entonces solo necesita asegurarse de que sus funciones c estén declaradas
Si su principal es C, entonces probablemente esté bien, excepto por las variables estáticas. Se supone que cualquier constructor con sus variables estáticas debe llamarse antes del inicio de main (). Esto no sucederá si C es tu principal. Si tiene muchas variables estáticas, lo mejor que puede hacer es reemplazar las variables estáticas con singletons.
fuente