У меня есть библиотека 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 обертка?
Обертка C ++ не требуется - вы можете просто вызывать функции C из кода C ++. IMHO, лучше не оборачивать код C - если вы хотите превратить его в код C ++ - хорошо, но сделайте полную переписать.
На практике, если предположить, что ваши функции C объявлены в файле с именем myfuncs.h, тогда в ваш код C ++ вы захотите включить их следующим образом:
extern "C" {
#include "myfuncs.h"
}
, чтобы дать им связь с C при компиляции с помощью компилятора C ++.
Я думаю, что писать обертку имеет смысл, только если это упрощает использование библиотеки. В вашем случае вы избавляетесь от необходимости передавать LIB*, и, предположительно, можно будет создавать объекты LIB в стеке, так что я бы сказал, что это улучшение.
Я бы также посмотрел на переименование LIB во что-нибудь получше, если ничего другого "Lib"
Change Name, вероятно, будет установщиком геттера ...
поэтому GetName (char *) SetName (char *)
, а затем посмотрите, как изменить его на std :: string вместо char *, если его SetName (const std :: string name) он примет в качестве параметра char *.
т.е. медленно переходить на измы C ++
В общем, я бы подошел именно так. Я бы также не использовал char *, а использовал std :: string.
Обычно я пишу только простую 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
Обертка C ++ сама по себе не требуется. Ничто не мешает вам вызывать функции C в вашем коде.