2010-05-03 14 views
9

Tengo una biblioteca C heredada, escrita en un formulario tipo OO. Las funciones típicas son como:Escribir un contenedor C++ para una biblioteca C

LIB *lib_new(); 
void lib_free(LIB *lib); 
int lib_add_option(LIB *lib, int flags); 
void lib_change_name(LIB *lib, char *name); 

Me gustaría utilizar esta biblioteca en mi programa en C++, así que estoy pensando en un envoltorio de C++ que se requiere. Lo expuesto todos parecen correlacionarse con algo como:

class LIB 
{ 
    public: 
     LIB(); 
     ~LIB(); 
     int add_option(int flags); 
     void change_name(char *name); 
... 
}; 

nunca he escrito en C++ ronda envoltorio C antes, y no pueden encontrar muchos consejos al respecto. ¿Es este un enfoque bueno/típico/sensato para crear un contenedor C++/C?

Respuesta

8

No es necesario un contenedor C++; simplemente puede llamar a las funciones C desde su código C++. En mi humilde opinión, es mejor no ajustar el código C, si quieres convertirlo en código C++, bien, pero haz una reescritura completa.

Prácticamente, asumiendo sus funciones C se declaran en un archivo llamado myfuncs.h entonces en su código C++ que se desea incluirlos como esto:

extern "C" { 
    #include "myfuncs.h" 
} 

con el fin de darles C vinculación cuando se compila con el compilador C++.

+0

¿No repetir? –

+0

@Neil: ¿No ser combativo? –

+6

No estoy de acuerdo (pero no downvote). Para libs de C simples, un contenedor a menudo es innecesario. Sin embargo, para las bibliotecas de C más complicadas, una envoltura C liviana puede ser invaluable. Un ejemplo viene a la mente: Tibco tiene una envoltura muy liviana alrededor de Tibrv que es inmensamente útil. –

2

Creo que tiene sentido escribir un contenedor si hace que el uso de la biblioteca sea más simple. En tu caso, estás haciendo innecesario pasar un LIB *, y presumiblemente será posible crear objetos LIB en la pila, así que diría que esto es una mejora.

+0

Todavía es necesario pasar objetos LIB :: LIB. Y asignar objetos LIB :: LIB en la pila solo le dará semántica automática, ya que probablemente el nuevo objeto C LIB se asignará en el montón en construcción. Pero a pesar de esto, el contenedor de C++ sigue siendo útil. –

2

Por lo general, me gustaría abordarlo. Tampoco usaría char * pero usaría std :: string.

1

Un contenedor de C++ no es necesario per se. No hay nada que te impida llamar a las funciones C en tu código.

1

También me miro el cambio de nombre LIB a algo un poco mejor, si no otra cosa "liberación" es probable que sea un regulador captador

Cambiar nombre ...

por lo GetName (char *) SetName (char *)

y luego mire cambiarlo a std :: string en lugar de char *, si su SetName (const std :: string name) aceptará un char * como parámetro.

es decir, mover lentamente a ismos ++ C

5

lo general sólo escribir una sencilla envoltura RAII en lugar de envolver cada función miembro:

class Database: boost::noncopyable { 
    public: 
    Database(): handle(db_construct()) { 
     if (!handle) throw std::runtime_error("..."); 
    } 
    ~Database() { db_destruct(handle); } 
    operator db_t*() { return handle; } 
    private: 
    db_t* handle; 
}; 

con el operador de conversión de tipo esto se puede utilizar con el Funciones C:

Database db; 
db_access(db, ...); // Calling a C function with db's type conversion operator