Я не знаю инструмента, который может сделать это автоматически, он может быть довольно сложным, если у вас есть классы в качестве аргументов для публичных функций в вашем API.
Но если ваш API прост и в основномиспользуя нативные типы, вы можете сделать это вручную, не слишком много работы.Вот краткий пример оболочки C для класса C ++.Допустим, это класс C ++ для переноса, назовем его test.h
:
class Test {
public:
Test();
int do_something(char* arg);
bool is_valid(); // optional, but recommended (see below)
};
Это ваш заголовок C test_c.h
:
typedef void* TestHandle;
TestHandle newTest();
int deleteTest(TestHandle h);
int Test_do_something(TestHandle h, char* arg);
И ваша реализация C будетфайл C ++ с функциями C, скажем test_c.cpp
:
extern "C" TestHandle newTest()
{
return (void*)new Test();
}
extern "C" int deleteTest(TestHandle h)
{
Test* this = static_cast<Test*>(h);
if (!this->is_valid())
return -1; // here we define -1 as "invalid handle" error
delete this;
return 0; // here we define 0 as the "ok" error code
}
extern "C" int Test_do_something(TestHandle h, char* arg)
{
Test* this = static_cast<Test*>(h);
if (!this->is_valid())
return -1; // here we define -1 as "invalid handle" error
return this->do_something(arg);
}
Метод is_valid()
предназначен для того, чтобы гарантировать, что вам не дали плохой дескриптор.Например, вы можете хранить магическое число во всех ваших экземплярах, тогда is_valid()
просто гарантирует, что магическое число существует.