我为C API编写了一个C ++包装类。
我的包装器类有一个在原始API中使用的typedef结构的私有实例成员。我不想修改API头文件,但我也想隐藏原始API的所有痕迹,所以我不想在包装类的标题中包含原始的API头文件。
我可能忽略了一些非常简单的东西,但我找不到它。 PIMPL是一个选项,但我更愿意在重构整个代码库之前寻找替代方案。
wrapper.hpp
class myWrapper
{
public:
myWrapper();
private:
originalTypedef *original; // forward declaration needed for originalTypedef
};
wrapper.cpp
#include "wrapper.hpp"
#include "originalAPI.h"
myWrapper::myWrapper()
{
original = originalAPI_get();
}
Main.cpp的
#include "wrapper.hpp"
int main()
{
myWrapper wrapper = new myWrapper();
}
答案 0 :(得分:3)
我能够快速思考的选项:
您可以在myWrapper.h中重复C API中的typedef
。
typedef struct the_original_struct_type originalTypedef;
在调用C API之前,您可以在void*
和myWrapper
到reinterpret_cast
中使用originalTypedef*
作为成员变量。
class myWrapper
{
private:
void* original;
};
答案 1 :(得分:1)
一个奇特的解决方案是编写一个读取original_c_api.h的代码生成器,并输出一个文件original_c_api_types.h,它只包含结构定义,类型等,但不包含任何函数,以及一个包含原始文件original_c_api_functions.h的文件。函数声明。然后wrapper.h包含original_c_api_types.h,wrapper.cpp包含wrapper.h和original_c_api_functions.h。代码生成器应作为makefile中的目标运行。
当然,如果您有权修改最简单的原始C api文件。
答案 2 :(得分:0)
您正在寻找的是像pImpl模式 - 您提供了一个C ++ API,并且实现从客户端进行了模糊处理:
标头文件
// forward declare obfuscated implementation
// we can do this because we're only using a ptr
class Implementation;
class Wrapper
{
public:
Wrapper();
~Wrapper();
void doSomething();
private:
Implementation * pImpl;
};
.cpp文件
#include "originalAPI.h"
class Implementation
{
public:
void doSomething()
{
OriginalAPI_DoSomething();
}
};
Wrapper::Wrapper()
{
this->pImpl = new Implementation();
}
Wrapper::~Wrapper()
{
delete pImpl;
}
void Wrapper::doSomething()
{
pImpl->doSomething;
}