2008-10-13 12 views
84

Tengo una biblioteca C++ que proporciona varias clases para administrar datos. Tengo el código fuente de la biblioteca.Uso de la biblioteca C++ en el código C

Quiero extender la API de C++ para admitir llamadas de función 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.), para que el lenguaje y la compatibilidad con la arquitectura no sean un problema.

¿Hay alguna razón por la cual esto es técnicamente no posible?

¿Hay gotcha's que debo tener en cuenta?

¿Existen recursos, código de ejemplo y/o documentación disponible al respecto?


Algunas otras cosas que he descubierto:

  1. la siguiente manera para envolver su C++ cabeceras que necesitan ser utilizado por el código C.

#ifdef __cplusplus 
extern "C" { 
#endif 
// 
// Code goes here ... 
// 
#ifdef __cplusplus 
} // extern "C" 
#endif 
  1. Mantener "reales" interfaces de C++ en ficheros de cabeceras que no están incluidos por C. Piense PIMPL principle aquí. Usar #ifndef __cplusplus #error ayuda aquí a detectar cualquier locura.
  2. Tenga cuidado con los identificadores C++ como nombres en el código C
  3. Enumeraciones de tamaño variable entre los compiladores C y C++. Probablemente no sea un problema si está utilizando la cadena de herramientas de GNU, pero aún así, tenga cuidado.
  4. Para las estructuras, siga el siguiente formulario para que C no se confunda.

    typedef struct X { ... } X 
    
  5. Entonces utilizar punteros para pasar alrededor de los objetos C++, sólo tienen que ser declarada en C como struct X donde X es objeto el C++.

Todo esto es cortesía de un amigo que es un asistente en C++.

+3

Un poco tarde, pero escribió un pequeño howto sobre el envoltorio C de C++: http://www.teddy.ch/c++_library_in_c/ – Teddy

Respuesta

62

Sí, esto es ciertamente posible. Usted tendrá que escribir una capa de interfaz en C++ que declara funciones con extern "C":

extern "C" int foo(char *bar) 
{ 
    return realFoo(std::string(bar)); 
} 

A continuación, se le llame foo() de su módulo C, que pasará la llamada a la función realFoo() que se implementa en C++.

Si necesita exponer una clase completa de C++ con miembros de datos y métodos, entonces es posible que necesite hacer más trabajo que este simple ejemplo de función.

+0

En caso de 'extern "C"' colocarse sólo en las declaraciones (y no en las definiciones)? Porque mencionó "la capa que declara funciones", pero su código de muestra también es una definición. En otras palabras, ¿deberíamos colocarlo en archivos de encabezado o archivos fuente? (¿O ambos?) – KyrSt

+0

@KyrSt: si tiene un archivo de encabezado con una declaración de función, entonces al menos debe poner 'extern" C "' allí . Su compilador le dirá si también debe ponerlo en la definición. –

3

puede mezclar el código C/C++.Si su función main() en C++, a continuación, sólo tiene que asegurarse de que sus funciones se declaran c

extern "C" 

Si su principal es C, entonces usted está probablemente bien, excepto para las variables estáticas. Se supone que todos los constructores con sus variables estáticas deben invocarse antes del inicio 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.

11

Main gotcha: las excepciones no se pueden capturar en C. Si existe la posibilidad de que una excepción aumente en el código de C++, escriba su código C o sus contenedores C++ con mucho cuidado. Por el contrario, no se requieren excepciones como los mecanismos (es decir, salto largo) en el código C (como se encuentra en varios lenguajes de scripting) para invocar destructores para objetos C++ en la pila.

+2

Gran punto acerca de las llamadas de salto largo. Si bien no los uso directamente, los marcos de prueba que uso los implementan. Algo para tener en cuenta. Gracias –

18

Preguntas frecuentes sobre C++ Lite: "How to mix C and C++ code".

Algunos errores se describen en las respuestas a estas preguntas:

  • [32.8] ¿Cómo puedo pasar un objeto de una clase de C++ a/de una función de C?
  • [32.9] ¿Puede mi función C acceder directamente a los datos en un objeto de una clase de C++?
Cuestiones relacionadas