使用Qt制作nodejs能用的64位dll
这个需求来自于工作,项目使用nodejs作为后台,然而出于性能考虑,需要使用调用动态库来解析指定设备的交互报文。
过程不再细述,最终的需求是,在windows/linux的64位服务器上,采用nodejs作为后台的项目,需要调用动态库
由于需要跨平台,自然选择了使用Qt来做动态库,虽然我最近才知道VS还有Linux版
1. nodejs仅支持C库而不支持C++库,这个意思并不是库内不能使用C++语法,而是接口是C风格,并且对外暴露的,采用Depends查看接口后,看到接口类型应该是C
这个比较容易解决,将Qt默认定义的以类的形式实现C++库改成接口就行了,无非是对外直接暴露接口,使用全局变量实例化接口类,在接口中直接调用接口的方法,并且在声明时一定要加上extern “C”
extern "C"; FSUSHARED_EXPORT char* dataFormat(char* pData, int iLen);
2. 64位动态库(windows)
也许有人会说32位的东西照样可以用在64位的机器上,不过这个东西一般指的是可执行程序,32位可执行程序当然可以在64位机使用,调用的是32位的动态库,但是64位的可执行程序只能调用64位动态库
这个就比较麻烦了,因为qt官方下载的windows离线包一直自带的是32位的全套库和32位的mingw编译器,要想获得64位bit,必须自己下载64位的mingw编译器并编译Qt源码,以下是步骤
环境: win10 64bit/Qt5.5.1(为了支持XP这是最晚的版本了,Qt5.6.0开始就对XP支持不太好),mingw4.9.2(Qt5.5.1默认搭配4.9.2)
- 下载mingw-w64
这步时不要使用在线下载工具,不是报错就是卡在中间,直接下载离线安装包,我是花了4个小时才得出这个结论并找到4.9.2的离线包,太坑了
这是下载地址,如果要使用其他版本,自己改一下url就行
-
下载Qt5.5.1源码
这个最简单,去官网下就行 -
使用下载的64位编译器,编译下载好的源码
此步主要参考https://blog.csdn.net/q1302182594/article/details/50197587,有几个非常重要的点需要明确,不然参考的教程作者写着全部顺利通过,但是自己编译起来就会各种错误- 下载离线包
- MINGW_4_9_2 这个环境变量必须建立,同时建议把64位编译器放到32位编译器同目录下,一般在xx\Qt\Qt5.5.1\Tools\目录下,这是一个强迫症患者的建议
- 不要怀疑为什么编译64位库却使用win32-g++/mingw32-make等参数
- -prefix 参数后建议填写与32位库同一个目录,一般在xx\Qt\Qt5.5.1\5.5\目录下,这是一个强迫症患者的建议
- 编译前先下载python安装包,并将其路径进入环境变量,参考这里
- 使用mingw32-make时,最好搭配以下两个参数一起,-k表示如果出现编译错误就尽量跳过继续编译,-j x表示采用几颗CPU核心一起编译,电脑在编译期间不使用的话,可以满负荷编译,速度可以快一些,作为参考,在不使用-j参数的情况下(默认单核心编译),大概使用了6小时完成编译,CPU型号是Inter Core i5-7300U
由于在编译时遇到了”File too big”错误,又因为项目急需,我直接采用了-k跳过错误,获得了绝大多数的64位库,如果有谁能完美编译,希望能告诉我方法
-
在Qt Creator上创建64位的构建套件(工具-选项-构建与运行)
- 创建64位编译器
- 创建Qt Version
- 创建构建套件
-
修改项目的构建套件为64位套件,并编译出dll
-
此处要注意,编译出的dll依赖于64位的Qt库,可以使用depends查看其依赖的模块,并一起拷贝给调用者
-
另外nodejs调用者要注意,nodejs调用的dll并不会识别在同目录下的Qt库,要把这些库放在系统目录下或者修改环境变量才能使用
-
2018/12/18新增File too big的解决办法
分别打开源码中的下面两个文件- qt3d\src\plugins\sceneparsers\assimp\assimp.pro
- qt3d\3dtools\qgltf\qgltf.pro
在末尾加入
if(win32-g++*:if(CONFIG(debug, debug|release))) {
QMAKE_CXXFLAGS += -Wa,-mbig-obj
}
编译时即可完美编译
一个忠告,不要没事重置系统,重装开发环境会把自己以前踩过的坑一个不漏地全部踩一遍