Запись обертки C++ для библиотеки C

У меня есть библиотека 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 обертка?

9
задан stripes 3 May 2010 в 21:14
поделиться

6 ответов

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

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

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

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

7
ответ дан 4 December 2019 в 11:40
поделиться

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

2
ответ дан 4 December 2019 в 11:40
поделиться

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

Change Name, вероятно, будет установщиком геттера ...

поэтому GetName (char *) SetName (char *)

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

т.е. медленно переходить на измы C ++

1
ответ дан 4 December 2019 в 11:40
поделиться

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

2
ответ дан 4 December 2019 в 11:40
поделиться

Обычно я пишу только простую 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
5
ответ дан 4 December 2019 в 11:40
поделиться

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

1
ответ дан 4 December 2019 в 11:40
поделиться