为C++库创建一个C包装器。

5
通过不透明指针将C++库包装到C中,是否会提供稳定的ABI接口?我很清楚什么是ABI接口以及为什么C++没有稳定的接口。这与名称混淆和其他许多内容有关。我知道C在这方面非常稳定。相比C ++,将C库封装到其他语言中也更容易。这两个因素是推动我为我的库创建C API的动力。
当将C++库包装到C时,底层代码仍然是C++。在我的情况下,它是具有boost共享指针和其他依赖项的c++。
因此,由于底层代码是用C++编写的,如何实现ABI稳定性。换句话说,共享库(.so、.dll等)中仍然编译了C++内容。
我想知道它是如何工作的。也许有人可以给我提供一个非常好的例子来解释这些内容。

1
你预计会遇到什么问题?我的意思是,你知道为什么C++ ABI被认为不稳定,对吗?这些相同的原因在你的情况下是否适用? - n. m.
1
可能是.def文件C/C++ DLLs的重复问题 - Dialecticus
2
当然,库中会编译一些C++相关的内容。但是接口将具有稳定的ABI,并且可以从几乎任何地方调用。请确保在API中捕获异常并将其转换为70年代旧式返回值。 - Erik Alapää
1
"其他特定问题" 如果您的库链接到标准C++库ABI x,并且其他某个库链接到标准C++库ABI y,则这两个库可能无法在一起使用(至少在某些平台上)。导出哪个接口都无所谓。这是所有C++库的问题。 "您是说代码必须用C重新编写吗?" 您是说C++不适用于编写库吗?显然,存在C++库,因此人们以某种方式能够应对ABI不稳定性。 - n. m.
显示剩余5条评论
2个回答

4

是的,您可以为C++实现创建稳定的C接口。当然,C接口只提供C功能。尽管如此,使用C++进行实际实现仍然很方便。以下是一个示例,其中您拥有一个带有函数模板的单个C++实现,并为某些变体提供C接口:

// Internal C++ implementation
template <typename T>
void
foo(T &a, const T &b)
{
    // do something
}


// C Interface
extern "C" {

void
sfoo(float *a, const float *b)
{
    foo(*a, *b);
}

void
dfoo(double *a, const double *b)
{
    foo(*a, *b);
}

} // extern "C"

因此,编译器将为T=floatT=double生成不同的实现:

  • 当然,您没有函数重载。所以你得手动进行名称编排。例如,sfoo代表float,dfoo代表double...(在C中也可以使用预处理器来完成这个任务,但是不容易阅读和维护。)
  • 您没有引用。所以接口暴露非const指针而不是引用。

1
如果正确执行,它将是您平台上 C 编译器的稳定 C ABI。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接