首先声明本人使用的Qt版本是qt-msvc2015_64-5.6.1, Visual Studio版本是VS2015(其实感觉Qt版本对问题的影响不大)。
问题1:本人最近在用Qt做一个项目的时候需要用到Matlab中的函数,于是想到了用Qt与Matlab的混合编程,即将Matlab的函数用VS2015的MSVC2015编译成动态链接库,然后再将其嵌入Qt程序中。具体流程可参照Qt5.9与Matlab2017b混合编程基本流程。
但是按照上述文章的流程操作后发现产生一些Qt编译错误,注意文章最后的一句话:
注意:在Qt Creator里编译时,应选择MSVC2015 64bit编译器,因为在Matlab里是用MSVC 201564位编译生成的DLL文件,若在Qt里使用其他的32位编译器将无法正常运行。
解决方法:查了一下发现自己的Qt用的是MinGW编译器,并没有使用MSVC2015 64位编译器,这才导致某些编译错误。MSVC编译器与MinGW编译器的区别可自行百度。要想使Qt用MSVC编译器进行编译,我所采用的方法是重新去下载并安装另一个版本的Qt,Qt下载网址:Qt下载
本人下的是qt-opensource-windows-x86-msvc2015_64-5.6.1(注意这个msvc2015指的是Qt默认采用msvc2015编译,64指的是64位,系统是64位的一定要选择带64的,后面的5.6.1是Qt版本,可任选,本人使用的Qt5.6.1)。
问题2:下载完带msvc2015编译器的Qt版本后编译时发现很多莫名其妙的错误(这是由于源文件或者头文件中有中文导致的错误),查了并没有什么语法错误(原来我用MinGW编译运行时是没有错误的),编译器却感觉无法识别我的这些符号。
查了很久才发现是MinGW编译器和MSVC编译器读取编码的方式不同导致的。首先得先了解一些知识:
1. Qt Creator的编辑器默认使用UTF-8编码来读取文本文件。而Visual Studio保存文件时默认采用的是本地编码,对于简体中文的Windows操作系统,这个编码就是GB2312。如果使用Qt Creator读取由Visual Studio创建的文件,那么编辑器就会以UTF-8编码格式读取GB2312编码格式的文件,出现中文乱码,因为这两套编码系统对汉字编码是不同的。至于英文部分不会乱码,是因为UTF-8和GB2312在单字节字符部分是兼容的。
2.MSVC在编译时,会根据源代码文件有无BOM来定义源码字符集。如果有BOM,则按BOM解释识别编码;如果没有,则使用本地字符集,对于简体中文的Windows操作系统就是GB2312。那么,当MSVC遇到一个没有BOM的UTF-8编码的文件时,它通常会把文件看作GB2312的来处理。如果文件全是英文没有问题,但如果包含中文,编译器就会出现误读。
解决方法:了解完这些知识后,总结一下就是MSVC编译器只认有BOM的UTF-8编码文件,而我们在Qt所创建的文件基本都是无BOM的UTF-8编译文件,所以MSVC编译器读取文件时会使用本地字符集,导致无法辨识我们的代码,产生编译错误。为了消除这些编译错误,本人采用的方法是“采用UTF-8编码字符集”的方法。
1. 首先,要把项目中所有的头文件和源文件全都转换成UTF-8+BOM编码保存。可使用Notepad++来对文件进行转码,即编码-以UTF-8格式编码-保存,即可将文件转成UTF-8+BOM编码格式。
2. 然后在要用到中文字符的头文件和源文件开头加上MSVC的一个宏:
#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif
这个宏告诉MSVC,执行字符集是UTF-8编码的,别瞎整成GB2312的。注:VS2015的_MSC_VER的值是1900
3. 编译运行即可,这个问题算是解决了。
问题3:经过上述操作以后,本人的项目运行时还有一个问题就是编译没有错误,但是程序运行会崩溃,又没有显示任何错误原因。用了调试器(MSVC编译器不带调试器,需自行下载配置,具体可百度,MinGW编译器自带调试器,所以不用自行下载调试器)调试后发现stack overflow的错误,即栈溢出。原来VS默认栈区为1M,导致栈空间不够溢出(本人项目用到很多局部变量)。相关知识了解可参照:从qt编程看内存分区
解决方法:解决这个问题最直接的方法就是改变默认栈的大小,具体方法是在.pro文件里加上一句话即可。
QMAKE_LFLAGS += /STACK:10240000
这里的10240000的单位是bit,指的是设置的栈空间大小(可根据需要自行设置大小),本人将栈空间修改为接近10M,再次运行后程序就没有崩溃了。
本人第一次写博客,上述所列出的问题都是本人做项目过程所遇到的问题,分享出来希望对大家有所帮助,有什么技术上的错误请大家指正!