Написание оболочки C ++ для библиотеки C - PullRequest
9 голосов
/ 04 мая 2010

У меня есть устаревшая библиотека C, написанная в форме типа OO. Типичные функции:

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

Я бы хотел использовать эту библиотеку в моей программе на C ++, поэтому я думаю, что требуется оболочка C ++. Казалось бы, все вышеперечисленное выглядит примерно так:

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

Я никогда раньше не писал оболочку C ++ вокруг C и не могу найти много советов по этому поводу. Это хороший / типичный / разумный подход к созданию оболочки C ++ / C?

Ответы [ 6 ]

7 голосов
/ 04 мая 2010

Оболочка C ++ не требуется - вы можете просто вызывать функции C из своего кода C ++. ИМХО, лучше не оборачивать код C - если вы хотите превратить его в код C ++ - хорошо, но сделайте полную переписывание.

Практически, если ваши функции C объявлены в файле myfuncs.h, то в коде C ++ вы захотите включить их следующим образом:

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

, чтобы дать им связь C при компиляции с компилятором C ++.

5 голосов
/ 04 мая 2010

Я обычно пишу только простую оболочку RAII, а не упаковываю каждую функцию-член:

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;
};

Оператор преобразования типов может использоваться с функциями C:

Database db;
db_access(db, ...);  // Calling a C function with db's type conversion operator
2 голосов
/ 04 мая 2010

Вот как правило, я бы подошел к этому. Я бы также не использовал char *, но использовал бы std :: string.

2 голосов
/ 04 мая 2010

Я думаю, что имеет смысл писать оболочку, только если это упрощает использование библиотеки. В вашем случае вы избавляетесь от необходимости передавать LIB *, и, вероятно, будет возможно создание объектов LIB в стеке, поэтому я бы сказал, что это улучшение.

1 голос
/ 04 мая 2010

Я бы также посмотрел на переименование LIB во что-то немного лучше, если ничего больше "Lib"

Изменение имени, вероятно, будет установщиком получения ...

так GetName (char *) SetName (char *)

и затем посмотрите, изменив его на std :: string вместо char *, если его SetName (const std :: string name) примет char * в качестве параметра,

т.е. медленно переходить к C ++ isms

1 голос
/ 04 мая 2010

Оболочка C ++ не нужна сама по себе. Ничто не мешает вам вызывать функции C в вашем коде.

...