MSVC_and_MinGW_DLLs

MSVC_and_MinGW_DLLs

http://www.mingw.org/wiki/MSVC_and_MinGW_DLLs

https://blog.csdn.net/zuishikonghuan/article/details/51918076

https://www.cnblogs.com/lichmama/p/4126323.html

https://www.zhihu.com/question/319640601

-------------------

两个编译器的c++ abi不兼容的,所以无法识别对方导出的符号完成链接。

但是可以用c语言中转,c的abi在所有编译器中都是相同的。

简单来说,把vc动态库所有导出接口都改为extern "C"形式即可,这样生成的动态库,MinGW是可以正确链接使用的,反之亦然。

但注意要规避一个问题,不要跨越动态库边界分配/释放内存,因为两边用的并不是同一套malloc/free。

并且发布程序时,两边的依赖都要带齐,比如vc库依赖的msvcrt等,mingw程序依赖的libpthread等。

 

关于c++对象,可以为其定义由纯虚函数组成的接口类,用c接口构造并返回接口指针,通过接口指针调用方法,这样的操作是没问题的。

不过虚接口的方式,其实是依赖了编译器的虚表结构,并没有在语言层面保证一定可用,最保险的方式,还是参考windows api的handle和linux api的fd。

即把ptr->function()改造为纯c的function(ptr)形式,这样还避免了虚函数的间接调用开销。

而需要运行时多态的虚函数,可以改为在ptr中显示保存函数指针来模拟虚表。

其实,各类大型c框架中的面向对象,就是这么实现的。

--------------------------

既然是动态库,也就是dll,那么mingw是可以链接的。

如果你确定dll里面的函数是stdcall调用方式,而不是cdecl,那么需要使用pexports工具生成一下模块定义文件(标准def文件)。

pexports.exe -v xxx.dll > xxx.def

然后使用mingw自带的dlltool工具,利用上一步生成def文件来创建.a文件。

dlltool --dllname xxx.dll --def xxx.def --output-lib libxxx.dll.a 

现在你可以通过libxxx.dll.a文件来做链接了。

如果你的dll里面的函数是cdecl方式调用的,那么就直接链接到dll文件就是。

------------------------------

不同工具链生成的库原则上是不能互相静态连接的,别说mingw和vc,哪怕vc的不同版本间,很可能都不行。

跟调用规范没关系,两个编译器都支持多种调用规范。只要调用方看到的函数签名上的调用规范和实现方一致,编译器就能生成正确的代码。

如果abi兼容,可以考虑用动态调用的方式使用dll。

对于纯c函数和c++“接口”(只有纯虚函数,没有任何其他成员的类),大概率abi是兼容的。

以使用纯c函数为例:

1 定义函数指针

2 调用LoadLibrary加载dll

3 调用GetProcAddress获取函数地址

4 利用函数指针调用此函数

========== End

原文地址:https://www.cnblogs.com/lsgxeva/p/12151772.html