matlab与C语言混合编程

要使用matlab来调用C或者C++写的代码就必须要配置环境,matlab是用mex来编译C或者C++代码的,编译生成.mexw64或者.mexw32为后缀的文件,matlab在调用时跟matlab调用本身的函数完全一样,使用起来非常方便。配置mex环境首先要在matlab中配置++编译器,如果你的计算机中已经安装了某个++编译器(例如vs或者gcc),在matlab命令行中直接输入"mex -setup"就会有相应的提示,然后选择下一步确定,编译器就设置成功了。如果没有安装C++的编译环境则需要自己下载一个C++编译环境,按照matlab中的提示就可以配置成功了。
接着就可以开始编写mex的文件了,下面举个例子,新建一个名为test.c的文件,代码内容如下:

/**********************************************************************
* 开发环境:matlab 2018a + VS2017
* 作    者:明志
* 日    期:2019.07.10
**********************************************************************/
#include "mex.h" //必须包含mex.h头文件,如果不包含则编译时会报错
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
     printf("hello,World!\n");
    printf("作者:明志\n");
}

上面的程序跟在C语言中在main函数上写效果上没有很大区别,但是mex的源文件一定要包含头文件"mex.h“,可以这样理解mexFunction函数可以相当于main函数,在这里相当于一个入口函数的作用,这个mexFunction函数有四个参数:nlhs(n left hand side) 等号左边参数个数,plhs(pointer left hand side)等号左边参数指针类型为指针数组,数组中保存的元素为输出矩阵的指针,另外两个参数是等号右边的个数和指针。
用mex编译C代码:首先在matlab中的命令行中输入mex <文件名> 回车就可以对使用接口函数编写的C代码,这里用 mex test.c 去编译,如果代码有错误则会编译不成功。编译成功之后再同一个文件目录下回出现一个后缀名为.mexw64的文件,这个就是matlab要执行的文件。
使用编译好的文件跟matlab本身的函数使用方法一样,是函数就有输入参数和返回参数,输入参数就是等号右边的参数,输出参数就是等号左边的参数,matlab中的函数允许有多个返回值,所以nlhs可以大于1。注意,指针plhs和prhs的类型为mxArray*,这是mex.h中定义的一种数据类型,这种数据类型存储数据的结构跟C语言中的数组不同,mxArray是按列来存储的,C语言中数组是按行来存储的,这点非常重要,如果不注意很容易出错。
matlab中的数据类型与C编程中指针和索引:
matlab中默认的数据类型是double,用class()函数可以看到变量的数据类型:
matlab与C语言混合编程_第1张图片
由上面可以知道当调用C代码时,C进行数据交互运算的类型最好也用double类型,因为在某些时候数据量大时调用可能会出错。
matlab对矩阵的存储方式和C语言对数据的存储方式不同,我们新建一个test1.c文件,代码如下所示:

/****************************************************************
* 开发环境:matlab 2018a + VS2017
* 作    者:明志
* 日    期:2019年06月17日 
****************************************************************/
#include "mex.h"

void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    double *Mat_i; //创建一个double类型的指针,用来获取输入矩阵的首地址
    int Row = 0; //定义行和列,用来保存矩阵的大小
    int Col = 0;
    int Sum = 0; //保存矩阵的大小
    
    Row = mxGetM(prhs[0]); //获取行和列
    Col = mxGetN(prhs[0]);
    Mat_i = (double *)mxGetPr(prhs[0]); //获取矩阵的首地址
    
    Sum = Row * Col; //获得矩阵的总大小
    printf("输入的矩阵为:\n");
    for(int i = 0; i < Sum; i++)
    {
        printf("%f\n",*(Mat_i + i)); //在C中输出矩阵
    }
}

使用mex编译test1.c文件,再在matlab中的命令行创建一个矩阵a,再将a传到test1中,结果如下图所示:

matlab与C语言混合编程_第2张图片

在上面可以看到,matlab中是按列去存储数据的(因为C是按行去存储数据的),这点是需要注意的;在来看看matlab中的矩阵,它不是C语言中的二维数组,而是一块连续可以通过指针来遍历的地址。在mex编译的.c代码中,mxGetPr()函数返回一个double*型的指针,指向矩阵的第一个元素,在matlab代码中调用:test1(a),那也就是prhs[0]是输入矩阵a的地址,如果有多个输入则就是prhs[1]…按照你输入的顺序来赋值。如果需要快速知道矩阵的大小或者为了防止指针遍历越界我们就需要准确知道传进来的矩阵的大小,matlab中帮我们提供了这样的函数,可以方便我们对矩阵进行索引,uint32 mxGetM(mxArray *)函数输入一个矩阵的指针,返回该矩阵的行数,uint32 mxGetN(mxArray *)函数返回列数,对行数和列数适当的计算,可以方便的访问矩阵元素,并且可以知道整个矩阵的大小。

你可能感兴趣的:(MATLAB)