保证C++库二进制兼容性的简单方法,C链接?

2022-01-09 00:00:00 binary compatibility c++ linkage

我不知道在 Windows 和 Linux 上保证 C++ 库的二进制兼容性的确切方法.但我认为,如果我使用 C 链接来制作所有公开的 API,我想我可以轻松地保证在 Windows 和 Linux 上的兼容性.

I don't know exact way to guarantee binary compatibility for C++ library on both Windows and Linux. But I think if I make all exposed APIs with a C linkage I think I can easily guarantee this compatibility on both Windows and Linux.

如下:

extern "C" int SomeAPI();

extern "C" int SomeAPI();

其余的函数肯定会用 C++ 编写.只有对外公开的 API 才会有 C 链接.

Rest of the functions surely will be written in C++. Only the APIs exposed to outter world will have C linkage.

并且公开的 API 必须是纯 C 函数 - 没有例外,没有使用 C++ 类型.

And the exposed API's must be pure C function - no exceptions, no C++ types are used.

我是对还是错?我有什么误解吗?

Am I right or wrong? Do I have any misunderstandings?

我想即使是 C 程序,我也可以使用这个库.

I think I can use this library even with C program also.

我想要实现的兼容性是编译器前向兼容和标准库前向兼容.

The compatibility I'd like to achieve is compiler forward compatibility and standard library forward compatibility.

而且我不能让它开源.我只需要关闭它.--> 我会努力开源的.

And I cannot make it opensource. I only have to close it. --> I will try making it open source.

我使用 boost 和 STL 来制作共享或静态 C++ 库.我也想知道不仅编译的兼容性,还有在操作系统中启动和运行的兼容性.

I use boost and STL for making shared or static C++ library. Also I wonder the compatibility not only for compiling but also for launching and running in and OS.

我说的对吗?

推荐答案

对于二进制兼容性,同样重要的是 应用程序二进制接口(ABI).

For binary compatibility, what also matters is the application binary interface (ABI).

顺便说一句,C++ 函数不仅可以返回一些结果,还可以抛出一些异常.您需要记录(即使您决定不抛出异常,这实际上很难实现,例如因为 new 可以抛出 std::bad_alloc,这可能发生在软件的某些内部层中).

BTW, C++ functions can not only return some results, but also throw some exceptions. You need to document that (even if you decide that no exceptions are thrown, which is actually difficult to achieve, e.g. because new can throw std::bad_alloc and this can happen inside some internal layers of your software).

请注意(特别是在 Linux 上)C++ 标准库的 ABI 确实随着编译器的不同版本而改变.例如,std::string-s 或标准 C++ 容器的实现 确实有所不同(在二进制级别以一种微妙的不兼容方式).您可以静态链接 C++ 标准库(但这可能并不总是足够的,或者很脆弱,例如,如果用户程序也需要它,因为他的代码是在 C++ 中的).

Notice that (notably on Linux) the ABI of the C++ standard library did change with various versions of the compiler. For examples, implementation of std::string-s or of standard C++ containers did vary (in a subtle incompatible way, at the binary level). You could statically link the C++ standard library (but this might not always be enough, or be brittle, e.g. if the user program also needs it because his code is in C++).

由于大多数 C++ 编译器和标准库在 Linux 上都是 免费软件,因此您可以深入他们的源代码以了解所有细节.这应该需要您多年的努力,并且您需要对此进行预算.

Since most C++ compilers and standard libraries are free software on Linux, you could dive into their source code to understand all the details. This should take you years of efforts and you need to budget that.

所以这比你相信的要难.至少,记录用于构建你的东西??的 C++ 编译器的版本,以及所涉及的 C++ 标准库的版本.

So it is harder than what you believe. At the very least, document the version of the C++ compiler used to build your thing, and the version of the C++ standard library involved.

另一种方法(我推荐)可能是让你的东西免费软件或开源并在上发布源代码github 或其他地方,并让您的用户编译您的源代码(使用 他的 C++ 编译器和 C++ 标准库).

Another approach (which I recommend) could be to make your thing free software or open source and publish the source code on github or elsewhere, and let your user compile your source code (with his C++ compiler and C++ standard library).

与各种 C++ 编译器和标准 C++ 库的二进制兼容性实际上很难实现,因为邪恶在于细节(如果你只发布一些二进制的东西).您可能会发布使用各种编译器版本编译的几个二进制文件(例如使用g++-5g++-6、<代码>clang++-4.0 等...).

Binary compatibility with various C++ compilers and standard C++ libraries is actually difficult to achieve, because the evil is in the details (if you release only some binary thing). You might publish several binaries compiled with various compiler versions (e.g. with g++-5, g++-6, clang++-4.0 etc...).

我不知道保证 C++ 库二进制兼容性的确切方法

I don't know exact way to guarantee binary compatibility for C++ library

这样的总体目标不切实际而且过于雄心勃勃.您最多可以发布几个二进制文件和文档,其中包含每个已编译的确切 C++ 编译器(以及版本和编译器选项)和 C++ 标准库.

Such a general goal is unrealistic and over-ambitious. At most you might publish several binaries and document with what exact C++ compiler (and version, and compiler options) and C++ standard library each have been compiled.

我想要实现的兼容性是编译器前向兼容和标准库前向兼容.

The compatibility I'd like to achieve is compiler forward compatibility and standard library forward compatibility.

一般来说不可能.过去,各种 C++ 编译器确实破坏了 ABI 兼容性(这已被记录在案).邪恶在于细节(所以即使它看起来大部分时间都有效,但它也可能经常出现问题).

This is impossible in general. Various C++ compilers did break ABI compatibility in the past (and this has been documented). The evil is in the details (so even if it apparently seems to work most of the time, it could often be buggy).

我说的对吗?

不,你错了,而且野心太大.最多你可以发布一个二进制文件(可能你应该发布几个个)并准确说明它是如何构建的(什么 C++ 编译器和版本,什么编译标志,什么 C++ 标准库和版本,甚至是什么 C标准库和版本;如果您使用一些外部 C++ 或 C 库 - 如 Qt、Boost、Sqlite 等... - 您还需要记录它们的版本).C++ 的二进制兼容性纯属虚构.

No, you are wrong and over-ambitious. At most you could release a binary (probably you should release several ones) and tell exactly how it was built (what C++ compiler and version, what compilation flags, what C++ standard library and version and even what C standard library and version; if you use some external C++ or C library - like Qt, Boost, Sqlite, etc... - you also need to document their version). Binary compatibility for C++ is a fiction.

您可以并且可能应该使用(尤其是在 Linux 上)包管理系统,例如为某些特定的 Linux 发行版(例如给定版本的 Debian 或Ubuntu).您将在二进制包中列出确切的依赖项.

You could and probably should use (on Linux particularly) package management systems, e.g. publish some .deb package for some particular Linux distributions (e.g. a given version of Debian or Ubuntu). You'll list exact dependencies in your binary package.

请注意,维护多个二进制版本(和二进制包)是一项需要预算的无聊工作.您可能会征求您的经理或客户的许可才能打开您的库的源代码(通常这需要较少的工作).例如,您的库可能在 GPLv3 许可下发布:开源程序可以自由使用它,但专有应用程序必须从您的公司购买一些其他许可证.

Be aware that maintaining several binary versions (and binary packages) is a lot of boring work that you should budget. You might ask permission from your manager or client to open the source of your library (and quite often this takes less work). For instance, your library might be published under GPLv3 license: open source programs could freely use it, but proprietary applications would have to buy some other license from your company.

相关文章