之前在运行别人论文的代码的时候,经常有遇到Matlab与C++混合编程的影子。实际上就是通过Matlab的Mex工具将C++的代码编译成 Matlab支持调用的可执行文件和函数接口。这样一方面可以在Matlab中利用已经编写好的函数,尽管这个函数是用C++编写的。实现了交流无国界, 没有江山一统的谁,只有四海之内皆兄弟的豪气。另一方面,取C++所长补己之短。Matlab擅长矩阵运算,但对循环操作的效率不及C++来得高效,例如 Hilbert矩阵的创建。所以对于具有大循环的运算,可以借C++之力来完成。
看到它的魅力,之前也一直想学下,可惜机缘不对。但在昨天缘分就到了。我需要用到一个论文给出来的代码,但是它的代码是C++的,而且还依赖了 OpenCV的库,基于Linux平台。这与实验室给我定出来的平台有很大的不同,我们是得统一基于Windows + Matlab来实现的,这样组内各个同学的工作才好统一。所以没办法了,就得把这个原作者的代码编译成Matlab支持的可执行文件。
一、初级
在使用MATLAB编译C/C++代码时,我们需要修改C/C++代码,在里面添加Matlab能支持的函数接口。这样Matlab才能调用它。然后再通过Matlab的Mex工具来编译它。下面就具体的举例子说明这两个步骤。
假设我们有一个很简单的C++代码,实现的就是两个double型数的加法:
mexAdd.cpp
- #include
- using namespace std;
-
- double add(double x, double y)
- {
- return x + y;
- }
1、修改代码文件
1)添加头文件mex.h
在我们的c++文件开头处添加头文件:
#include"mex.h"
2)添加接口函数mexFunction()
mexFunction的定义为:
void mexFunction(int nlhs, mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
}
首先,这个函数是没有返回值的。它不是通过返回值把c++代码的计算结果传回Matlab的,而是通过对参数plhs的赋值。例如我们在Matlab中,调用这个add函数一般是这样:
>> a = 0.5; b = 0.8;
>> c = add(a, b);
那mexFunction怎么将输入参数a和b传入给c++的add函数,然后就怎么把计算结果返回给c呢?这些粗重活全部通过mexFunction的四个参数来实现:
nlhs: 感觉是number of left hand size
parameters,也就是Matlab调用语句左边的变量个数,实际上就是需要返回给Matlab的返回值变量有多少个。例如上面c =
add(a, b);就只有一个返回参数c,所以nlhs就是1;
plhs: 感觉是pointer of left hand size
parameters,也就是函数返回参数的指针。但它是一个指针数组。换句话说,它是一个数组,每个元素是个指针,每个指针指向一个数据类型为
mxArray的返回参数。例如上面c = add(a, b);就只有一个返回参数c,所以该数组只有一个指针,plhs[0]指向的结果会赋值给c。
nrhs: 这个是number of right hand size parameters,也就是Matlab调用语句右边的变量个数。例如上面c = add(a, b),它给c++代码传入了两个参数a和b,所以nrhs为2;
prhs:这个是pointer of right hand size
parameters,和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了a,prhs[1]指向了b。要注意prhs
是const的指针数组,即不能改变其指向内容。
因为Matlab最基本的单元为array,无论是什么类型也好,如有doublearray、 cell array、struct
array……所以a,b,c都是array,b = 1.1便是一个1x1的double
array。而在C语言中,Matlab的array使用mxArray类型来表示。所以就不难明白为什么plhs和prhs都是指向mxArray类型
的指针数组(参考资料[1])。
那mexFunction函数的函数体要怎么写呢?怎么样通过这个接口函数将Matlab的参数和c++代码中的相对应的参数联系起来呢?我们先把这个代码全部展现出来。
最后的mexAdd.cpp是这样:
mexAdd.cpp