c++ - C++ 二进制代码能否通过 native C 接口(interface)变得可移植?有什么限制?

标签 c++ c shared-libraries compatibility binary-compatibility

我经常使用该技术将我的高性能 C++ 类包装为一个薄的 C 层,我将其编译为共享库,然后用其他编程语言(例如 Python)加载它们。

根据我在这里和那里的阅读,我了解到要使它起作用的唯一要求是让函数接口(interface)仅使用 native 类型或这些类型的结构。 (因此,intlongfloatdouble 等以及它们的任意级别的指针)。

我的问题是:假设完整 ABI compatibility在各种编译器之间,这是我要实现与共享库的完整 API 兼容性的唯一要求吗?

为什么不能移植C++库?这是我的理解:

情况 1:考虑 std::string 类型。它在内部包含一个 char* 空终止字符串和一个大小整数。 C++ 标准并没有说明哪一个应该先出现(对吧?)。这意味着如果我将 std::string 放在函数接口(interface)上,两个不同的编译器可能会以不同的顺序排列它们,这是行不通的。

案例 2:考虑为具有虚方法的类继承和虚表。 C++ 标准不要求 vtable 指针必须去的地方的任何特定位置/顺序(对吗?)。它们可以位于类的开头,位于任何其他变量之前,也可以位于类的末尾,位于所有其他成员变量之后。同样,在函数上连接此类将不一致。

我的第一个问题之后的另一个问题:这个问题不会也发生在函数调用中吗?还是编译成二进制后就什么都不重要了,类型就没有意义了? RTTI 元素是否会导致问题,例如,如果我将它们放在 C 包装器接口(interface)中?

最佳答案

没有 C++ ABI 的部分原因是没有 C ABI。正如 Bjarne Stroustrup ( source ) 所述:

The technical hardest problem is probably the lack of a C++ binary interface (ABI). There is no C ABI either, but on most (all?) Unix platforms there is a dominant compiler and other compilers have had to conform to its calling conventions and structure layout rules - or become unused. In C++ there are more things that can vary - such as the layout of the virtual function table - and no vendor has created a C++ ABI by fiat by eliminating all competitors that did not conform. In the same way as it used to be impossible to link code from two different PC C compilers together, it is generally impossible to link the code from two different Unix C++ compilers together (unless there are compatibility switches).

缺少 ABI 为编译器实现提供了更多自由,并允许将语言传播到多种不同类型的系统。

在 Windows 上,有一些特定于平台的依赖项依赖于编译器输出结果的方式,一个例子来自 COM需要以特定方式布置纯虚拟接口(interface)的地方。所以在 Windows 上,大多数编译器至少会同意这一点。

Windows API 使用 stdcall调用约定,因此在针对 Windows API 进行编码时,对于如何将参数传递给函数有一套固定的规则。但这同样取决于系统,并且没有什么可以阻止您编写使用不同约定的程序。

关于c++ - C++ 二进制代码能否通过 native C 接口(interface)变得可移植?有什么限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42361693/

相关文章:

c++ - 不需要其元素是默认元素和可复制构造的容器

c++ - 如何从进程内部确定 CPU 和内存消耗

c - 通过父级执行命令时使用管道

linux - ctypes.util.find_library 是否符合 Linux 中的 "usual"库链接实践?

C++ - 字符串和 LPCWSTR 之间的转换

c++ - 我可以在没有 COM 的情况下将 x-headers 添加到 Lotus Notes 电子邮件吗?

c++ - 如何进行一维 "valid"卷积?

c - 在 C 中发出清除输入流

c++ - 如何从共享库中调用函数?

c++ - 如何减少编译时间 : in case of including an untouched header file