在 Windows 世界中的 C 编译器(MSVC 和 GCC/MinGW)的特定情况下,您对二进制兼容性的假设是正确的。可以将 GCC 编译的 C 接口 DLL 链接到 Visual Studio 中的程序。这就是 ffmpeg 等 C99 项目允许开发人员使用 Visual Studio 编写应用程序的方式。只需从 DLL 中使用 Microsoft 工具链中的 lib.exe 创建导入库。反之亦然,使用 mingw.org 的 pexports 或更好的 mingw-w64 的 gendef 工具,可以为 MSVC 生成的 DLL 创建 GCC 导入库。
当您进入 C++ 接口世界时,这种方便的互操作性就会失效,因为 MSVC 和 GCC 的 ABI 不同且不兼容。它可能有效,也可能无效,没有做出任何保证,也没有(目前)正在努力改变它。此外,调试信息显然是不同的,直到有人在 GCC 中编写了与 MSVC 调试器兼容的调试信息生成器/写入器(当然还有 gdb 支持)。
我认为 C99 并没有特别改变函数声明或符号定义中处理参数的方式,所以这里也应该没有问题。
请注意,正如 Vijay 所说,仍然存在架构差异,因此在链接到 AMD64 库时不能使用 x86 库。
还要回答您关于封闭源代码二进制文件和为所有可用编译器/架构分发版本的附加问题。
这正是您创建封闭源代码二进制文件的方式。除了导入库之外,隐藏 DLL 的导出也很重要,这使得 DLL 本身无法用于链接(如果您不希望客户端代码使用库中的私有函数,请参见例如dumpbin /exports
on的输出) MSOffice DLL,那里有很多隐藏的东西)。您可以使用诸如此类的东西使用 GCC(我相信,从未使用或尝试过)来实现相同的目标__attribute(hidden)
......
一些编译器特定点:
MSVC 通过 /MT、/MD 和 /LD 提供了四个(好吧,实际上在较新版本中只剩下三个)不同的运行时库。最重要的是,您必须为每个版本的 Visual Studio(包括 Service Pack)提供构建以确保兼容性。但那是封闭源代码二进制文件和 Windows 对你来说......
GCC没有这个问题;MinGW 始终链接到 Windows 提供的 msvcrt.dll(自 Windows 98 起),与 /MD 等效(也可能与 /MDd 等效的调试库)。但是我有两个版本的 MinGW(mingw.org 和 mingw-w64)不保证二进制兼容性。后者更完整,因为它提供 64 位选项和 32 位选项,并提供更完整的标头/库集(包括 DirectX 和 DDK 的大部分)。