在c++头文件中声明一个C类型定义

forward declare a C typedef in a C++ header

本文关键字:一个 定义 类型 c++ 文件 声明      更新时间:2023-10-16

我为一个C API编写了一个c++包装器类。

我的包装器类有一个私有实例成员,该成员是原始API中使用的类型定义结构。我不想修改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();
}

我能快速想到的选项:

  1. 您可以在myWrapper.h中重复C API中的typedef

    typedef struct the_original_struct_type originalTypedef;
    
  2. 在调用C API之前,可以使用void*作为myWrapperreinterpret_castoriginalTypedef*的成员变量。

    class myWrapper
    {
       private:
          void* original;
    };
    

一个奇特的解决方案是编写一个代码生成器,它读取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。代码生成器应该在make文件中作为目标运行。

当然,如果你有权修改原始的C api文件,这是最简单的解决方案。

您正在寻找的是类似于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;
   }