Matlab在处理矩阵运算等数学类操作时很方便,但是在循环处理上效率相较VS低了很多,所以经常会用到mex对Matlab的.m混编C文件,调用C函数,提高代码运行效率。以上是我的一点粗浅的理解,欢迎大家补充。
要进行Matlab和C混编,首先需要安装Matlab和VS或VC(Windows系统)。我软件的版本是Matlab2014a和VS2010,只要可以互相兼容调用,编译器的版本倒不是区别很大。
下面介绍一个Matlab通过Mex混编C的简单例子。代码主要功能是输入数组b和整数a,输出数组c的每个元素等于b的元素加上a的值。代码.m和.cpp内容如下:
% Matlab代码 % 其中test为混编调用C函数 a = 1; b = [ 1 : 10 ]; c = test( b, a ); c
下面是C++代码,命名为test.cpp:
准备好代码之后,值得说明的是,代码.m中调用test函数,是C++混编的,在C++代码中依赖文件名以区分,即C++命名为调用的函数名test.cpp。要对该文件进行混编,需要在Matlab下选择编译器,这个其他博客中有说的很清楚的,我就简单带过了。具体可以参考:点击打开链接
Matlab中输入mex -setup后,看到可以选择的编译器。
单击或输入命令都可以,我选的是C++,如下图:
下面对test.cpp进行编译,直接输入mex test.cpp命令,注意当前命令窗口所在路径包含test.cpp文件,或在同一文件路径下。
编译成功后,在文件栏也会有mex文件产生,如下图:
当然程序复杂之后,编译过程往往不会那么顺利,可能会出现很多错误,如果是cpp编写错误,Matlab还是很人性化的提供很多提示,如下图:
这个时候把错误调对了,基本上就可以正确编译了,但是往往不会那么顺利,所以就到了今天想分享的重点,就是Matlab与VS混编时时候跨平台调试debug。这个我也是在盲调了好久之后,才发现原来可以这么跨平台调的,反应迟钝。。。盲调应该是所有coder的噩梦(可能这个词是我创的)。
当然,要进行跨平台调试的前提是把语法错误全部搞定,才能编译通过。要debug的话,编译命令只需改成mex test.cpp -g就可以了!Matlab也会产生相应pdb文件。
这个时候用VS打开test.cpp,找到工具栏-调试-附加到程序:
点开之后看到的是:
找到Matlab,点击附加,就可以看到VS与Matlab的一些通信中间消息:
注意增加几个断点(不然程序还是不能停的= =)。然后回到Matlab页面,进行正常调试:
只要设置断点,按键F5或点击调试,之后就会跳转到VS里面的断点处:
这样调试就很方便了!变量之类的内容的都可以看见,而且鼠标放在数组处可以看到当前读取的内容值,真的很人性化。从此以后,再也不用害怕混编啦!
另外,我说一下,混编里面常出现的但也容易忽略的错误吧(我经常犯),注意到会简约不少不必要的时间。Matlab里面初始化数组默认是double类型的,因为没有特别明显的参数区别,所以在传参的时候时常会忽略这一点,我的示例里面用到的b在Matlab中声明的时候,虽然赋值都是整数,但机器内给的是double型,所以初次调试的时候,返回的结果还是不对。
这个错误还是比较明显的,因为我的程序里面没有设置检验类型的代码(建议大家规范一些就加上判断传参类型),所以程序运行下来没有报错,但是结果是错的,不过这个错误明显是数据类型不匹配导致的。后来检查一下,发现确实是。
这个只需要改一下test.cpp里面的接收参数指针类型,由int改为double就解决了。
还有一个常遇到的是C代码里面有程序问题,调试过程中时常遇到错误,会导致Matlab崩溃。这个时候如果让Matlab继续运行,我们再修改代码之后mex可能会提示pdb正在使用,没办法更新,目前我想到的办法就是重启Matlab,希望能找到不那么麻烦的方法。欢迎大家一起讨论!祝混编一切顺利!