前言:本篇文章主要通过一个简单的例子程序对C-Mex进行一个初步的说明。前期的环境搭建(包括安装Matlab和gcc编译器)就不在这里赘述了。

  在看文章之前,建议初学者先检查一下Matlab的mex配置。运行一下“mex -setup”,看看是否已经在Matlab中配置了相应的gcc编译器。如果没有,按照提示一步步改吧。

  

  首先,为什么要使用C-Mex?说开了,就是程序的效率问题。最近,我在做一个并行化的项目,原来的程序是用Matlab编写的,运行时间为6个小时以上,在我改成Matlab和C(或C++)混编之后,运行时间缩减到2分钟不到。天!180多倍的加速比,不敢想象!当然,并不是每一个程序改成C之后都能得到这么大的提速,关键还要看程序本身的计算量和访存的频繁程度。

  那么,mex文件是什么呢?Mex文件其实是其他语言与Matlab的接口。通过这个接口,我们可以像使用Matlab函数(即.m文件)一样的方式使用其他语言编写的程序。例如,下面一个最最简单的矩阵加法的例子。

matlab主函数(main.m):

 %编译c文件
mex addVector.cpp; %初始化参数
A = [ ; ];
B = [ ; ]; %调用mex文件
C = addVector(A,B);

  该Matlab程序非常简单,首先编译文件addVector.cpp,然后声明连个变量A和B。最后将A和B作为函数addVector的参数,调用函数并返回结果保存为C。这里,你可能会注意到addVector.cpp是c++文件,其实并没有什么区别,编译器会自动帮你识别区分c和c++程序。不过,要是你有强迫症的话,也可以写成.c文件,前提是你的文件里面没有诸如类和对象这些C语言没有的东西(C这个单身狗怎么可能有对象呢,哈哈哈......)。

  咦,那使用语句“mex addVector.cpp”来编译我们的C文件,编译后的文件是怎样的呢?来来来,请看下面:

  

  你看看那蓝色的家伙“addVector.mexw64"就是我们使用mex命令编译后的可执行文件了。在使用的时候,我们只需要喊一下她的名字”addVector“,然后把参数传进去,她就会老老实实的听你话啦!嘿嘿嘿,是不是很美妙呢!那么,后缀名"mexw64"又是什么东西,这个嘛!其实后缀名“mexw64”中的“mex”是告诉大家这个文件是mex文件啦!然后,“w64”是说这个文件只能在64位的windows系统下使用啦!没有什么的呐。

  我说她会老老实实听话,难道你信了啊?当然,我没有骗你,但是你肯定要先对她好才行呀。那么,怎么对她好呢?接下来,我来给大家介绍咋们的正主“addVector.cpp"。咋们轻解罗衫,细细品尝。请细看:

 #include "mex.h"
#include <stdio.h> //nlhs为输出参数个数,nrhs为输入参数个数
//plhs为输出参数指针,prhs为输入参数指针
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
{
//获取输入数据
int i=;
double* inputMatric_A = (double*)mxGetData(prhs[i++]);//matlab传过来的参数默认为double类型
double* inputMatric_B = (double*)mxGetData(prhs[i++]); //获得第一个参数的行数和列数
int numRowsA = (int)mxGetM(prhs[]);
int numColsA = (int)mxGetN(prhs[]);
printf("numRowsA = %d\n",numRowsA);
printf("numColsA = %d\n",numColsA); //生成输出输出
plhs[] = mxCreateDoubleMatrix(numRowsA,numColsA,mxREAL); //三个参数分别为行数,列数和数据类型,mxREAL为实数
double* outputMatric_C = (double*)mxGetData(plhs[]); //创建指针指向输出数据 //计算并将结果放入输出数据区
int dataSize = numRowsA * numColsA; //矩阵A元素总个数
for(i=; i<dataSize; i++)
{
outputMatric_C[i] = inputMatric_A[i] + inputMatric_B[i];
}
}

  嘻嘻!代码有点长,整整29行呀!先看一下头文件吧,计算最前面#include那两行啦!”#include “mex.h"呢,是把那些你要用到的函数的函数声明先包含进来,你看看下面调用的那些函数,所有你没看到过的就是啦!”include <stdio.h>"只是C的io流头文件而已呐,没有什么的,不要告诉我你不会C,瞬移回去学完再来。

  前方高能,请看第6行代码,没错,就是那个函数“void mexFunction( int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])"。你问我这是什么鬼?我TM哪知道了。我只知道它是她的心脏,必须存在。你写C程序不是还要一个main函数作为入口吗?那你写mex程序也要一个入口呀,这个入口就是”mexFunction“啦!入口,入口,懂不!我知道你懂,嘿嘿嘿!咦,那这个函数怎么有那么多个参数呀!我记得main函数只有两个参数呀,叫什么”argc“和”argv的“。小傻瓜,人家是C-Mex啦,跟C哪能一样呀,虽然我们都没有对象。既然你想知道,那我就跟你讲清楚咯。看到没,四个参数:”nlhs“,”plhs“,”nrhs“,”prhs“。哇塞,长得好像!n开头的是参数个数,”nlhs“和”nrhs“分别是输出参数个数和输入参数个数,像我们上面的例子就是nlhs=1,nrhs=3啦。p开头的呢就是指向输入数据的指针啦,”plhs“和”prhs“分别是指向输出数据和输入数据的指针。你看看,人家传递的参数是指针,多好,不用把数据再复制一遍。Matlab那个家伙声明了两个变量A和B,把他们放到仓库(内存)里了,然后把仓库的位置(内存地址,即指针)告诉我,我(C)要用的时候就可以直接去那里取啦!嘻嘻,我把仓库里的原材料(A和B)拿来做成蛋糕(outputMatric_c),然后放到我的小仓库(plhs[0])里,然后Matlab就可以来拿去吃啦!原汁原味,又不浪费多余的空间。

  在来细细斟酌一下具体的内容。9~11行,我们把参数一个接一个拿出来。记得哦!我们拿到的都是指针哦!Matlab传递的参数一般是double类型的咯,所以你的"inputMatric_A"等都要是double类型的咯。如果你从Matlab传过来的参数是float类型的就改成float类型的咯。

  既然有了输入数据,那么我们还要做一个放小蛋糕的仓库(输出数据)呀!那么,这个仓库(内存)要多大呢?你喜欢咯!14~21行就是在做这件事情咯,我们得到参数prhs[0]的行号和列号就是要用来规定仓库的大小的呐。numRowsA x numColsA,这么大哦!

  虽然我们给输出参数plhs[0]分配了空间,但是我们肯定是不能直接操作这个指针的呀!我们用另一个指针”outputMatric_C”指向这个内存空间,然后把结果保存在"outputMatric_C"就可以啦!毕竟plhs[0]和“outputMatric_C”本质上是一个东西,只是他们类型不一样,一个是mxArray类型的,一个是double类型的。

  突然发现自己废话有点多啊!还是赶紧总结一下吧,别说话,看图:

  

  首先先写C或C++的源文件咯,写完编译一下生成可执行文件咯!搞定之后,就可以在Matlab程序中调用咯,输入参数和输出参数的参数你自己决定咯。

  好咯,这篇文章就写到这里咯!我要去吃饭啦!闪人!!!

Matlab && C-Mex Round 1的更多相关文章

  1. Matlab与C/C++联合编程之Matlab以MEX方式调用C代码(五)完整过程加示

    如下为本人亲证代码: 一: 编译器的安装与配置(环境不同,显示结果不同) 要使用MATLAB编译器,用户计算机上应用事先安装与MATLAB适配的以下任何一种ANSI C/C++编译器: 5.0.6.0 ...

  2. Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(四)

    利用Matlab与VC++联合编程,既可在C语言程序中打开Matlab引擎,调用Matlab的ToolBox函数和作图函数,也可在Matlab中调用C代码生成的动态链接库文件,用以加快执行速度.缩短开 ...

  3. Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(三)

    最近写了个Matlab程序,好慢呐……所以开始学习Matlab与C/C++混合编程.下面写了个测试代码,显示一个Double类型矩阵中的元素. 源代码 #include "mex.h&quo ...

  4. Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(二)

    如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数: double add(double x, double y) { return x + y; } 现在我想要在Matlab中使用它,比 ...

  5. matlab设定mex接驳的C/C++编译器

    使用C/C++编写核心算法,使用matlab调用算法.做上层封装,通常是提升效率并提供易用性的一个不错的选择. mex需要设定接驳的C/C++编译器,官方文档在这里:https://ww2.mathw ...

  6. Matlab以MEX方式调用C源代码【转载】

    原文地址:http://blog.sina.com.cn/s/blog_468651400100coas.html 这是自己整理的一个对应的文档:<Matlab以MEX方式调用C源代码> ...

  7. matlab设置mex失败

    更新 使用matlab2017b时,又报错, >> mex -setup 警告: Xcode is installed, but its license has not been acce ...

  8. VC 编译 MATLAB 的 mex 文件

    VC 编译 MATLAB 的 mex 文件mex 文件是 MATLAB 调用其他程序设计语言程序或算法的接口.在 Windows 环境中,mex 文件是扩展文件名为 DLL 的动态链接库,可以在 m ...

  9. Matlab与C/C++联合编程之Matlab以MEX方式调用C/C++代码(一)

    MEX文件是一种可在matlab环境中调用的C语言(或fortran)衍生程序,mex的编译结果实际上就是一个带输出函数mexFunction 的dll文件. 中文名 mex文件 外文名 MATLAB ...

  10. Mac Mojave(10.14.1)执行Matlab的mex报错

    先装了matlab2018b,发现很频繁的crash,同时考虑到要跑的代码在>=2017a时就计算错误,于是转战matlab2016b matlab2016b安装后,执行mex -setup报错 ...

随机推荐

  1. 哈哈:sqlserver2008附加数据库时操作系统错误5(拒绝访问)错误5012的解决办法

    老师说:无论干什么,出错了,先大笑三声.如果人多了,在心里也要大笑三声.哈哈哈!!! 刚刚重装系统完后,然后想学习.自己去安装sqlserver2008数据库,完之后想附加之前的数据库.可是当我一点确 ...

  2. JS+HTML5的Canvas画图模拟太阳系运转

    查看效果:http://hovertree.com/texiao/html5/9.htm 地球自传 http://hovertree.com/texiao/html5/8.htm 代码如下: < ...

  3. js中Unicode转义序列

    将某一中文字符转义,可采取在线工具进行转义,http://tool.chinaz.com/tools/unicode.aspx "哈哈" ==="\u54c8\u54c8 ...

  4. Sap SE16n 修改表数据

    SAP中直接修改表.视图的Tcode有SE16N和SM30. 其中使用SE16N修改表需要先输入命令&SAP_EDIT, 回车左下角显示激活SAP编辑功能后,就可以对相应的表进行新增.删除.修 ...

  5. Linux学习心得之 Linux下命令行Android开发环境的搭建

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Linux学习心得之 Linux下命令行Android开发环境的搭建 1. 前言2. Jav ...

  6. Sharepoint学习笔记—习题系列--70-576习题解析 -(Q116-Q120)

    Question  116 You are helping a corporate IT department create a SharePoint 2010 information archite ...

  7. HashMap和SparseArray的性能比较。

    HashMap和SparseArray可以实现相似的功能. 但SparseArray是Android定义的,在键是整数时,他比HashMap的性能更高,因为HashMap使用的是Integer对象, ...

  8. 三种POST和GET的提交方式

    向服务器提交数据有两种方式,post和get.两者的区别主要有三点,安全性.长度限制.数据结构.其中get请求安全性相比较而言较差,数据长度受浏览器地址栏限制,没有方法体.两种都是较为重要的数据提交方 ...

  9. SwipeRefreshLayout + RecyclerView 实现 上拉刷新 和 下拉刷新

    下拉刷新和上拉刷新都用SwipeRefreshLayout 自带的进度条 布局 <?xml version="1.0" encoding="utf-8"? ...

  10. LinearLayout布局问题

    LinearLayout是平时开发中很常见的线性布局方式,分为水平和竖直2种,笔者在实际使用中发现了如下问题,希望能帮到别人. 横着的LinearLayout,凡是设置x坐标的属性都不起作用,比如la ...