在 MSVC 中使用 MinGW 编译的 C++ 库的方式

这篇文章介绍一种能让 MSVC 使用 MinGW 编译的 C++ 库的方式。(这里只讨论C++库的共 享,MinGW编译出来的C库好像使用可以直接在MSVC中使用的。)

为什么使用这种方式

有时候你需要编写跨平台的back-end程序,由不同的系统平台去实现fore-end。如果使 用 GCC,你可以通过交叉编译得到适用于不同平台的back-end 库。为了实现 Windows 的 GCC 交叉编译你需要用到 MinGW,而 Windows 上很多人使用 MSVC 编写程序,包括你的 fore-end 程序。这样依赖你就面临了需要让 MSVC 使用 MinGW 编译的库的问题了。

MinGW 输出的文件类型

静态库

如果你编译的是静态库,你会得到

  • libxxx.a

如果你编译的是动态库,你会得到

  • libxxx.dll.a
  • libxxx.dll

.dll.a 是动态库的导出库,在链接过程中会使用到,所以你需要使用 #pragma comment(lib, "libxxx.dll.a") 这种方式在fore-end中使用它完成编译, libxxx.dll 在运行中需要使用,你可以把他放到输出的bin文件的同一目录或者系统动 态库查找路径的目录中。

使用方式

libxxx.a这种类型的 C++ 库是没有办法使用的,因为 MSVC 使用静态库格式是 libxxx.lib.a.lib 格式的C++库内部结构不一样,直接使用会报错说格式不 对。

libxxx.dll这种类型的动态库也没有办法直接使用。MinGW使用GCC编译器,而MSVC 使用 的是微软的编译器 CL。这两种方式对于 C++ 的 name mangling 的实现方式不一样。所 以你没有办法直接在 MSVC 上使用 MinGW 编译的库文件,因为在最终链接在一起的时候, 同一个名字会因为不同的name mangling 而变成不同的名字,最终导致无法链接成功。

幸运的是,C++兼容C代码,而C的名称是可以不进行name mangling的,所以为了能够使得 MSVC能够使用MinGW编译的C++库,你需要给你的库添加一层C接口,并给这些C接口加上: extern "C"修饰使得这些库拥有C链接属性。可参考stack ovferflow上的一些答案 ^1^3

参考