首页 > 解决方案 > 如何编写用于从 C 访问 C++ 类成员的 Wrapper(具有继承和构造函数)

问题描述

在大多数问题中,我看到了一个简单类的包装器,它没有构造函数、继承,只调用一个void*用于创建和销毁的函数以及一个 foo 函数。

对于像下面这样的结构,应该如何创建一个包装器来从CCode 访问类成员。

myHeader.h for c++
-------------------
class childA:public parentA {private: void logger() override}

class childB:public parentB 
{ 
  private: /*some members*/ 
  protected: /*some members*/
  public: 
      explicit childB(childA* a);
}
class parentB
{
  protected:
      MyType object;
  public:
      boolean Init(MyType obj); /*the implmentation is object=obj*/
}

现在在C代码中,我想访问object. 我应该如何为此编写包装器?

Object type is a function pointer => typedef S32(*IoFunc)(Msg&);
where S32 is unsigned int, Msg is a struct.

谢谢你的帮助。

标签: c++cvisual-c++extern

解决方案


对代码进行非客观化非常简单:

#ifdef __cplusplus
extern "C"
{
#endif
    void* construct_me(/*arguments*/);
    void* get_object(void* obj);
    void delete_me(void* obj);
#ifdef __cplusplus
}
#endif

然后定义它们:

extern "C"
{
    void* construct_me(/*arguments*/)
    {
        return static_cast<void*>(new parentB(/*arguments*/));
    }
    void* get_object(void* obj)
    {
        return static_cast<void*>(&(static_cast<parentB*>(obj)->object));
    }
    void delete_me(void* obj)
    {
        delete static_cast<parentB*>(obj);
    }
}

如果该类型可以在 C 中使用,那么您可以这样做:

Type get_object(void* obj)
{
    return static_cast<parentB*>(obj)->object;
}

而不是将其转换为void*.

继承不会改变任何事情。这是相同的机制,除了如果您有虚函数,您仍然应该为继承的类包装所有虚函数(即使 A 从 B 继承,将 A* 转换为 void* 为 B* 也是 UB)。

PS:我认为这与提供的链接中的答案没有什么不同。


推荐阅读