Я хочу иметь только 2 функции extern C, которые взаимодействуют с API. Затем внутри статического.lib я хочу, чтобы мой класс выполнял всю работу. Но он не должен быть видимым снаружи.
Я могу сделать это с помощью только чистых функций C, объявив их статическими внутри блока компиляции, но как это сделать с классом?
Если я хорошо понимаю ваш вопрос:
Если это так, трюк - просто использовать неименованное пространство имен:
В вашем библиотечном источнике у вас есть что-то вроде этого:
namespace { // anonymous
class U { // class visible only to the library
public:
int y;
U() :y(0) { cout << "U\n"; }
void mrun() { y++; }
};
}
void f() {
U x;
...
}
Затем вы можете использовать свою библиотеку из мира аутсайда:
extern void f(); // declare the function (in a header)
f(); // invoke the function
Даже если вспомогательный класс будет объявлен во внешнем мире:
class U { public: int y; U(); void mrun(); };
Он не сможет использоваться, и связывание ошибок будет сгенерировано, если у него возникнет соблазн использовать U. Это связано с тем, что неназванные пространства имен уникальны для каждого блока компиляции.
Если вы используете одно и то же решение, но без анонимного пространства имен, вспомогательный класс будет виден и ссылка будет успешной.
Возможно, вы можете зеркально отобразить API-интерфейс класса, используя функции C, примерно так:
class Cpp
{
int i = 0;
public:
int get_i() { return i; }
void set_i(int i) { this->i = i; }
};
// C code has a void* as a handle to access
// the correct instance of CPP
extern "C" void* new_Cpp()
{
return new Cpp;
}
extern "C" void delete_Cpp(void* cpp)
{
delete reinterpret_cast<Cpp*>(cpp);
}
extern "C" int Cpp_get_i(void* cpp)
{
return reinterpret_cast<Cpp*>(cpp)->get_i();
}
extern "C" void Cpp_set_i(void* cpp, int i)
{
return reinterpret_cast<Cpp*>(cpp)->set_i(i);
}