繁体   English   中英

为 C 库编写 C++ 包装器

[英]Writing a C++ wrapper for a C library

我有一个以 OO 类型形式编写的遗留 C 库。 典型功能如下:

LIB *lib_new();
void lib_free(LIB *lib);
int lib_add_option(LIB *lib, int flags);
void lib_change_name(LIB *lib, char *name);

我想在我的 C++ 程序中使用这个库,所以我认为需要一个 C++ 包装器。 以上似乎都映射到以下内容:

class LIB
{
    public:
         LIB();
         ~LIB();
         int add_option(int flags);
         void change_name(char *name);
...
};

我以前从未编写过 C++ 包装器,也找不到关于它的太多建议。 这是创建 C++/C 包装器的好/典型/明智的方法吗?

不需要 C++ 包装器 - 您可以简单地从 C++ 代码调用 C 函数。 恕我直言,最好不要包装 C 代码——如果你想把它变成 C++ 代码——很好,但要完全重写。

实际上,假设您的 C 函数是在名为 myfuncs.h 的文件中声明的,那么在您的 C++ 代码中,您将希望像这样包含它们:

extern "C" {
   #include "myfuncs.h"
}

为了在使用 C++ 编译器编译时为它们提供 C 链接。

我通常只写一个简单的 RAII 包装器,而不是包装每个成员函数:

class Database: boost::noncopyable {
  public:
    Database(): handle(db_construct()) {
        if (!handle) throw std::runtime_error("...");
    }
    ~Database() { db_destruct(handle); }
    operator db_t*() { return handle; }
  private:
    db_t* handle;
};

使用类型转换运算符,这可以与 C 函数一起使用:

Database db;
db_access(db, ...);  // Calling a C function with db's type conversion operator

我认为只有在使库的使用更简单的情况下编写包装器才有意义。 在您的情况下,您不需要传递 LIB*,并且大概可以在堆栈上创建 LIB 对象,所以我会说这是一个改进。

这通常是我将如何处理它。 我也不会使用 char* 而是使用 std::string。

本身不需要 C++ 包装器。 没有什么可以阻止您在代码中调用 C 函数。

我也会考虑将 LIB 重命名为更好的东西,如果没有别的“Lib”

更改名称很可能是一个getter setter ...

所以 GetName(char *) SetName(char *)

然后考虑将其更改为 std::string 而不是 char*,如果它的 SetName(const std::string name) 它将接受一个 char* 作为参数。

即,慢慢转向 C++isms

假设 C 库的分配/释放实例是create_instancedestroy_instance ,并且它公开了一个名为call_function的函数,并且它没有提供用于深度复制实例的 API,这将起作用:

class Wrapper
{
public:
    Wrapper(): m_instance(create_instance(), destroy_instance) {}

    explicit operator bool() const
    {
        // null check
        return bool(m_instance);
    }

    void callFunction()
    {
        call_function(m_instance.get());
    }

private:
    std::unique_ptr<instance, decltype(&destroy_instance)> m_instance;
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM