最近在封装SDK,想做一个Windows下通用的,比如给出的动态库可以被Qt MinGW版本使用、也可以被Qt MSVC版本使用;还可以被VS使用。Ok,需求目标有了,接下来就是论证是否可以实现以及如何实现了。
一、Qt MinGW调用VS 编译的C库
之前和大家分享过Qt使用海康相机SDK显示图片的例子,在该例子中使用了海康的C动态库,Qt使用起来完全没有问题。
我的最终目标就是编一个和海康一样的动态库,可以被Windows下大多编译器识别调用即可。
目前的情况是SDK内部本身使用了第三方库,该库有源码、同时也提供了基于VC14的动态库,但是由于使用的Qt是MinGW版的,所以无法直接使用该库。为了先出第一版的SDK,选择了直接将第三方库使用MinGW进行编译,也就是只能供Qt调用。经过测试之后,使用Qt5.5.1编译的动态库,可以被Qt5.14使用(具体对应的编译器分别是mingw492_32和mingw73_32)。
接下来验证VS2013编译的动态库如何被Qt MinGW愉快的调用。
经过艰难困苦的测试,VS编译的C动态库,可以被Qt链接,VS导出库的头文件时应加上extern “C”;而且Qt对链接VS编译库的方式也有要求。
链接海康相机完全没问题
LIBS += $$PWD/3rdLib/mvs/win32/lib/MvCameraControl.lib
链接VS编译的C库要这样写:
LIBS += -L$$PWD/Lib/test/win32/lib/ -lTestlib
但是使用VS编译导出的C++动态库确实不行的。这里先简单说下extern “C”的作用:在C++调用C代码时会使用这个语法,而C代码中本身是没有这个命令的;该命令告诉编译器通过C的内部标识符去寻找对应函数,为什么这样?通过一个简单例子来说明下:
add(int x, int y)
对于上述这样的函数,由于C++具有重载功能,经过编译器编译后内部标识符类似这种,add_int_int;C编译器产生的内部标识符是这样的,_add。
这样C++程序就可以直接调用C程序了。
话说回来,目前得出的结论是VS编译的C库可以愉快的被Qt MinGW调用。
效果如下:
二、Qt MinGW调用VS编译C++生成的C库
前面说的是Qt直接调用VS编译的C库,这次做的测试是VS调用Opencv的库,然后再将其封装C库,测试Qt MinGW能否调用,这里可以确定的是可以调用。
吐槽一下,VS在链接opencv几十个库时,需要挨个写一遍,太难了。(当然也可能是我的方法不对。)
以后有机会写下VS怎么编译和链接动态库。
三、小结
之所以这么迫不及待的发出来,是因为在网上找到可用的资料比较少。
Qt可直接调用VS编译出的C库:
① VS导出函数时需使用extern “C”
②注意链接C库的形式
Qt无法直接调用第三方使用VC的编译的C++动态库,但是可以通过VS中转成C库供Qt MinGW使用。