C 中的交叉编译器二进制兼容性

发布于 2024-11-26 17:09:04 字数 416 浏览 3 评论 0原文

我需要验证一些我有疑问的事情。如果共享库(.dll)是用 C 编写的,符合 C99 标准并在编译器下编译。说MinGw。然后根据我的经验,它是二进制兼容的,因此可以从任何其他编译器使用。比如说 MS Visual Studio。我说的是我的经验,因为我已经尝试过不止一次成功了。但我需要验证这是否是一个规则。

另外我想问如果确实如此,那么为什么完全用 C 编写的库(例如 openCV)不为每个不同的操作系统提供编译的二进制文件?我知道明显的原因是设置所有编译时参数,但除此之外没有其他参数,对吗?

编辑:我添加了一个附加问题,我认为这是对原始问题的逻辑扩展。这不就是创建一个闭源库的方式吗?由于提供源代码的选项已经被排除在外,因此提供二进制文件是唯一的选择。在这种情况下,为尽可能多的体系结构提供二进制文件是理想的结果,而 C 是在系统和编译器之间实现最佳可移植性的明显选择。正确的?

I need to verify something for which I have doubts. If a shared library ( .dll) is written in C, with the C99 standard and compiled under a compiler. Say MinGw. Then in my experience it is binary compatible and hence useable from any other compiler. Say MS Visual Studio. I say in my experience because I have tried it successfully more than once. But I need to verify if this is a rule.

And in addition I would like to ask if it is indeed so, then why libraries written completely in C, like openCV for example don't provide compiled binaries for every different OS? I know that the obvious reason would be to set all the compile-time parameters, but other than that there is none right?

EDIT: I am adding an additional question which I see as a logical extension to the original. Isn't this how one would go and create a closed source library? Since the option of giving source goes out of the window there, giving binaries is the only choice. And in that case providing binaries for as many architectures as possible is the desired result, with C being an obvious choice for having the best portability between systems and compilers. Right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

江南烟雨〆相思醉 2024-12-03 17:09:04

在 Windows 世界中 C 编译器(MSVC 和 GCC/MinGW)的特定情况下,您对二进制兼容性的假设是正确的。可以将 GCC 编译的 C 接口 DLL 链接到 Visual Studio 中的程序。这就是 ffmpeg 等 C99 项目允许开发人员使用 Visual Studio 编写应用程序的方式。只需使用 Microsoft 工具链中的 lib.exe 从 DLL 创建导入库即可。反之亦然,使用 mingw.org 的 pexports 或更好的 mingw-w64 的 gendef 工具,可以为 MSVC 生成的 DLL 创建 GCC 导入库。

当您进入 C++ 接口世界时,这种方便的互操作性就会崩溃,其中 MSVC 和 GCC 的 ABI 不同且不兼容。它可能有效,也可能无效,没有做出任何保证,并且(当前)没有做出任何努力来改变这一点。而且,调试信息显然是不同的,直到有人在 GCC 中编写与 MSVC 调试器兼容的调试信息生成器/编写器(当然还有 gdb 支持)。

我认为 C99 没有对函数声明或符号定义中处理参数的方式进行任何具体更改,因此这里也不应该有任何问题。

请注意,正如 Vijay 所说,仍然存在架构差异,因此链接到 AMD64 库时不能使用 x86 库。


还可以回答有关闭源二进制文件和为所有可用编译器/体系结构分发版本的其他问题。

这正是创建闭源二进制文件的方式。除了导入库之外,隐藏 DLL 的导出也非常重要,这使得 DLL 本身对于链接毫无用处(如果您不希望客户端代码使用库中的私有函数,请参见 < code>dumpbin /exports 在 MSOffice DLL 上,那里有很多隐藏的东西)。您可以使用 GCC 实现相同的功能(我相信,从未使用或尝试过),使用诸如 __attribute(hidden) 等之类的东西...

一些编译器特定点:

  1. MSVC 附带了四个(嗯(实际上在较新的版本中仅剩下三个)不同的运行时库通过 /MT、/MD 和 /LD。除此之外,您还必须为每个版本的 Visual Studio(包括 Service Pack)提供一个版本,以确保兼容性。但这对你来说是闭源二进制文件和 Windows...

  2. GCC 没有这个问题; MinGW 始终链接到 Windows 提供的 msvcrt.dll(自 Windows 98 起),相当于 /MD(也可能是相当于 /MDd 的调试库)。但我有两个版本的 MinGW(mingw.org 和 mingw-w64),它们不保证二进制兼容性。后者更完整,因为它提供了 64 位选项和 32 位选项,并提供了更完整的头文件/库集(包括 DirectX 和 DDK 的大部分)。

In the specific case of C compilers (MSVC and GCC/MinGW) in the Windows world, you are correct in the assumption of binary compatibility. One can link a C interface DLL compiled by GCC to a program in Visual Studio. This is the way C99 projects like ffmpeg allow developers to write application wiht Visual Studio. One only needs to create the import library with lib.exe found in the Microsoft toolchain from the DLL. Or vice versa, using mingw.org's pexports or better, mingw-w64's gendef tool, one can create a GCC import lib for a MSVC produced DLL.

This handy interoperability breaks down when you enter the C++ interface world, where the ABI of MSVC and GCC is different and incompatible. It may work, it may not, no guarantees are made and no effort is (currently) being done in changing that. Also, debugging info is obviously different, until someone writes a debug information generator/writer in GCC that is compatible to MSVC's debugger (along with gdb support of course).

I don't think C99 specifically changes anything to function declarations or the way arguments are handled in symbol definitions, so there should be no problem here either.

Note that as Vijay said, there is still the architecture difference, so a x86 library can't be used when linking to an AMD64 library.


To also answer your additional question about closed source binaries and distributing a version for all available compilers/architectures.

This is exactly the way you would create a closed source binary. In addition to the import library, it is also very important to hide exports from the DLL, making the DLL itself useless for linking (if you don't want client code to use private functions in the library, see for example the output of dumpbin /exports on a MSOffice DLL, lots of hidden stuff there). You can achieve the same thing with GCC (I believe, never used or tried it) using things like __attribute(hidden) etc...

Some compiler specific points:

  1. MSVC comes with four (well, actually only three remaining in newer versions) different runtime libraries through /MT, /MD, and /LD. On top of this, you would have to provide a build for each version of Visual Studio (including Service Packs) to assure compatibility. But that is closed source binary and Windows for you...

  2. GCC does not have this problem; MinGW always links to msvcrt.dll provided by Windows (since Windows 98), equivalent with /MD (and maybe also a debug library equivalent with /MDd). But I there are two versions of MinGW (mingw.org and mingw-w64) which do not guarantee binary compatibility. THe latter is more complete as it provides 64-bit options as well as 32-bit, and provides a more complete header/library set (including a substantial part of DirectX and DDK).

最后的乘客 2024-12-03 17:09:04

一般规则是,如果您的操作系统/CPU 组合具有标准 ABI,并且如果该 ABI 对于您的语言来说足够强大,则大多数编译器将遵循该 ABI,因此将是二进制兼容的,允许您链接库(共享或static)用不同的编译器编译的程序到用其他编译器编译的程序就好了。

问题是大多数 ABI 都相当薄弱——它们是围绕 C 和 FORTRAN 等低级语言设计的,并且可以追溯到 C++ 等面向对象语言之前的时代。因此,它们往往缺乏对 C++ 所需的函数重载、用户定义运算符、异常、全局构造函数和析构函数、虚函数、继承等的支持。

在设计 C++ 时就认识到了这一缺陷,这就是为什么 C++ 有 extern "C" ——这会导致编译器将自身限制为某些函数的标准 ABI,同时禁用所有额外的 C++ 功能。 ABI 一般不支持。

The general rule is that IF your OS/CPU combination has a standard ABI, and IF that ABI is powerful enough for your language, most compilers will follow that ABI and as a result will be binary compatible, allowing you to link libraries (shared or static) compiled with different compilers to programs compiled with other compilers just fine.

The problem is that most ABIs are fairly weak -- they're designed around low-level languages like C and FORTRAN and date back to the days before object oriented languages like C++. So they tend to lack support for things like function overloading, user-defined operators, exceptions, global contructors and destructors, virtual functions, inheritance, and such that are needed by C++.

This lack was recognized when C++ was designed which is why C++ has extern "C" -- which causes the compiler to limit itself to the standard ABI for certain functions, while disabling all the extra C++ features that the ABIs generally don't support.

╰◇生如夏花灿烂 2024-12-03 17:09:04

编译到特定体系结构的共享库或 dll 可以链接到由针对相同体系结构的其他编译器编译的应用程序。 (我所说的架构是指处理器/操作系统的组合)。但对于库开发人员来说,针对所有可能的架构进行编译是不切实际的。此外,当库以源代码形式分发时,用户可以构建针对其特定需求进行优化的二进制文件。

A shared library or dll compiled to a particular architecture can be linked to applications compiled by other compilers that target the same architecture. (By architecture, I mean a processor/OS combination). But it is not practical for a library developer to compile against all possible architectures. Moreover, when a library is distributed in source form, users can build binaries optimized to their specific requirements.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文