【问题标题】:Yet another how to create a C wrapper of a C++ class? [closed]还有一个如何创建 C++ 类的 C 包装器? [关闭]
【发布时间】:2022-01-07 19:53:58
【问题描述】:

我想为我编写的 C++ 库创建一个 C 包装器。

我找到的所有示例和 SO 的答案:

使用 void,typedef void myhdl_t

木马结构:struct mather{ void *obj; };

# .h
struct mather;
typedef struct mather mather_t;

# .cpp
struct mather{
    void *obj;
};

mather_t *mather_create(int start){
    mather_t *m;
    CPPMather *obj;

    m      = (typeof(m))malloc(sizeof(*m));
    obj    = new CPPMather(start);
    m->obj = obj;

    return m;
}

从 C++ 基类派生结构

# .h
struct Foo;

#.cpp
struct Foo : public FooInternal {
    using FooInternal::FooInternal;
};

struct Foo* foo_new() {
    try {
        return new Foo;
    } catch(...) {
        return nullptr;
    }
}

我的情况:

我想要一个这样的分配 C 函数:

int alloc_function(struct Foo** foo){
  if (foo==nullptr)
    return -EFAULT; // The user gives nullptr
  if (*foo!=nullptr)
    return -EFAULT; // already allocated
  
  // error: Incompatible pointer types assigning to 'struct Foo *' from 'Foo *'
  *foo = new Foo;

  // No error but Clang-Tidy: Do not use static_cast to downcast from a base to a derived class
  *foo = static_cast<struct Foo*>(new Foo);

  return 0;
}

我了解 Clang-Tidy 不是编译器错误,但我仍然希望以正确的方式进行操作。

  • 编写 C 包装器的最佳实践是什么?有什么真实的例子吗?

【问题讨论】:

  • error: Incompatible pointer types assigning to 'struct Foo *' from 'Foo *' 发布完整的minimal reproducible examplestatic_cast&lt;struct Foo*&gt;(new Foo); 只是 reinterpret_cast 它。

标签: c++ c


【解决方案1】:

我的情况:

我想要一个这样的分配 C 函数:

int alloc_function(struct Foo** foo){

Foo 已经是 C++ 类型。使用不同的。使用void * 指针。

struct CFoo {
   void *pnt;
};

extern "C"
int alloc_function(struct CFoo* foo) {
  if (!foo)
     return -EINVAL; // That is no EFAULT, it's EINVAL.
  try { 
     foo->pnt = reinterpret_cast<void*>(new Foo);
  } ...
  return 0;

}

【讨论】:

  • 与其将new Foo 包裹在try/catch 中,不如使用new (std::nothrow) Foo。它没有抛出失败,而是给出一个空指针。
  • @KamilCuk 谢谢,木马结构是最好的方法/实践吗?从类派生结构的“我的案例”怎么样?为什么它比使用typedef void foo_t 更好?
  • @Peter 我不知道,感谢您的最佳实践!
  • is the trojan structure the best way/practice? 是主观的,很大程度上取决于具体情况。 How about "My case" with derived struct from the class? 怎么样?确保调用具有正确类型的析构函数。 why is it better than using typedef void foo_t? 允许从 C 端的编译器进行静态类型检查。 better to use new (std::nothrow) Foo. Instead of throwing on failure 虽然这是真的,Foo 构造函数也可以抛出 - 我们不想泄漏异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多