Matlab + VS | Matlab2014a + VS2010 Win7 混编调试


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:

// function [ c ] = test( b, a );
// Input:
// b : the number series
// a : the number to add

// Ouput:
// c : the result number series

//  Chang Liu, Jul 13 2016


# include "mex.h"
# include "math.h"


void mexFunction( int nlhs, mxArray *out[], int nrhs, const mxArray *in[] )
{
	// Check whether the inputs are correct
	if ( nrhs != 2 )
	{
        mexErrMsgTxt("test: Not correct input arguments! 2 Input Argument expected!");
    }
    
    /* Declare input variables */       
    
    mwSize N;
	double *b;
	int a;

	// Record the number of the first input argument
	// Array: b
	N = mxGetNumberOfElements( in[ 0 ] );
	b = ( double* ) mxGetPr( in[ 0 ] );

	// Get the scalar value: a
	a = ( int ) mxGetScalar( in[ 1 ] );


	/* Declare output variables */

	// Allocate the output space
	out[ 0 ] = mxCreateNumericMatrix( N + 1, 1, mxUINT32_CLASS, mxREAL );

    int *c = ( int * )mxGetData( out[ 0 ] );

	// This is a simple example
	// add a to each element in b saved in c
	// You can write your program as you wish
	for( int i = 0; i < N; i++ )
	{
		c[ i ] = b[ i ] + a;
	}

	mexPrintf("B + A Program Done: \t Array b adds value a equals to ...\n");

	return;
    
}
% Matlab代码
% test为调用的C函数

a = 1;
b = [ 1 : 10 ];
c  = test( b, a );
c

准备好代码之后,值得说明的是,代码.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,希望能找到不那么麻烦的方法。欢迎大家一起讨论!祝混编一切顺利!








  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值