gpt4 book ai didi

c++ - 用 C 和 C++ 接口(interface)编写库,用哪种方式包装?

转载 作者:IT老高 更新时间:2023-10-28 22:31:58 25 4
gpt4 key购买 nike

在准备一个库(我们称之为 libfoo)时,我发现自己面临以下两难境地:我是否将其编写为带有 C 包装器的 C++ 库:

namespace Foo {
class Bar {
...
};
}

/* Separate C header. #ifdef __cplusplus omitted for brevity. */
extern "C" {
typedef void *FooBar;
FooBar* foo_bar_new() { return new Foo::Bar; }
void foo_bar_delete(FooBar *bar) { delete bar; }
}

或者将其编写为带有 C++ 包装器的 C 库更好:

/* foo/bar.h. Again, #ifdef __cplusplus stuff omitted. */

typedef struct {
/* ... */
} FooBar;

void foo_bar_init(FooBar *self) { /* ... */ }
void foo_bar_deinit(FooBar *self) { /* ... */ }

/* foo/bar.hpp */

namespace Foo {
class Bar {
/* ... */
FooBar self;
}

Bar::Bar() {
foo_bar_init(&self);
}

Bar::~Bar() {
foo_bar_deinit(&self);
}
}

你更喜欢哪个,为什么?我喜欢后者,因为这意味着我不必担心我的 C 函数会意外出现异常,而且我更喜欢 C 作为一门语言,因为我觉得它是一个较小的语义雷区。其他人怎么看?

编辑:很多好的答案。谢谢大家。可惜我只能接受一个。

最佳答案

小点:

当您编写 C 库时,它在任何地方都很有用 - 在 C、C++(带有包装器)和许多其他语言(如 Python、使用绑定(bind)的 Java 等)中,最重要的是它只需要 C 运行时。

在写C++ wrapper的时候也需要写一个C wrapper,但是并不是你想的那么简单,例如:

c_api.h:

extern "C" {
typedef void *Foo;
Foo create_foo();
}

c_api.cpp:

void *create_foo() 
{
return new foo::Foo();
}

怎么了?它可能会抛出!并且程序将崩溃,因为 C 没有堆栈展开语义。所以你需要这样的东西:

void *create_foo() 
{
try {
return new foo::Foo();
}
catch(...) { return 0; }
}

这适用于每个 C++ api 函数。

所以我认为编写一个 C 库并提供一个单独的 C++ 包装器是更好的解决方案。

它也不需要与 C++ 运行时库链接。

关于c++ - 用 C 和 C++ 接口(interface)编写库,用哪种方式包装?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3912298/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com