c++引用matlab类,在MATLAB中调用封装好的C++函数的方法

背景

MATLAB有强大的矩阵运算能力以及丰富的函数库,可以用于算法的仿真以及快速验证某些算法思路。MATLAB的UI层是利用基于JVM利用Java实现的,而部分算法的底层则是封装了C/C++以及Intel提供的汇编指令集。因此MATLAB在用于计算时的速度是非常之快的。但是有的时候我们经常看到,虽然一些论文或者文章中描述了算法,并且作者也在个人主页上po处了源代码。但是这些算法的细节我们的是看不到的,可能是由于专利的原因,也可能是算法中的某些参数是经过了大量验证而作者并不想公布的。因此,对于很多图像类的算法,作者们都是采用了将算法的核心部分利用MATLAB自带的C编译器mexcc封装为一个.mexw64(64位系统)或.mexw32(32位系统)文件,然后在MATLAB的.m文件中通过函数名直接调用这些封装的函数。这样既保证了算法的速度,又可以保留必要的细节。那么如何实现这个呢?其实很简单,下文会详细介绍

方法

之前写过一篇关于如何在VS中调用MATLAB函数的方法,既要安装MATLAB RUNTIME COMPILER又要设置工程的附加库和包含目录,同时C和C++文件调用MATLAB还有区别,非常的麻烦。但是如果发过来,通过MATLAB来调用C/C++函数就相对而言过程简化了很多。

1. C++端的代码

为了方便,我们用一个简单的demo来举例子。假设我们需要封装原来的C++函数:

// Arithmetic_Operation.cpp

// 本函数实现了两个double型参数输入的四则运算,并保存在res数组中,顺序为加减乘除

#include

void Arithmetic_Operation( double* res, double a, double b )

{

res[0] = a + b;

res[1] = a - b;

res[2] = a * b;

res[3] = ( b == 0 ? 0 : a / b ) ; // check whether divide is zero

return;

}

我们要将Arithmetic_Operation函数封装为一个.mexw64文件并在MATLAB中调用,具体的做法是:

新建一个.cpp文件,这里需要注意的是:

cpp文件名就是在MATLAB中编译了之后以供调用的函数名,所以请不要随意命名需要编译的cpp文件。

我们将文件名为ArithmeticOp.cpp

也就是说,在编译好了之后在MATLAB中调用方式是:

[ res ] = ArithmeticOp(a, b);

下面是ArithmeticOp.cpp文件的实现:

/* ArithmeticOp.cpp */

#include "mex.h" //一定要包含这个头文件,这个头文件是MATLAB为MEX编译专门提供的头文件

#include

// 被封装的函数声明

void Arithmetic_Operation( double* res, double a, double b );

/*

* 请注意下面的这个mexFunction函数,如果需要使用mex编译C++函数,一定要使用这个函数

* mexFunction就像#include "mex.h"一样是必须的,相当于是MATLAB和C++的一个接口函数

* 这个函数的四个参数都是有用的,它们分别代表的意思是:

* nlhs: 输入参数个数(MATLAB调用语句中,等号左边的参数个数) plhs: 输入参数列表

* nrhs: 输出参数个数(MATLAB调用语句中,等号右边的参数个数) prhs: 输处参数列表

*/

void mexFunction( int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[] )

{

if (nlhs != 1 || nrhs != 2 )// 判断调用参数数量是否正确

{

printf("Invalid Argument Usage!\n");

exit(0);

}

// get input data

double* a = mxGetPr(prhs[0]); // 输入参数列表,下标0是第一个输入参数

double* b = mxGetPr(prhs[1]); // 类似于C++ main函数的两个参数(int argc, char** argv)的使用

double* result = (double *)malloc(4*sizeof(double));

// invoke

Arithmetic_Operation(result, *a, *b);

// output data

plhs[0] = mxCreateDoubleMatrix(4, 1, mxREAL);// 用于创建一个double型的矩阵,三个参数分别是矩阵的行,列,类型

double* output = (double *)mxGetPr(plhs[0]); // mexGetPr()函数是mex.h中提供的用于获取输入输出参数地址的函数

for (int i = 0; i < 4; i++)

output[i] = result[i];

free(result);

return;

}

/* 被封装的函数 */

void Arithmetic_Operation( double* res, double a, double b )

{

res[0] = a + b;

res[1] = a - b;

res[2] = a * b;

res[3] = ( b == 0 ? 0 : a / b ) ; // check whether divide is zero

return;

}

// end of implementation

这样,一个简单的MATLAB调用C++函数的demo就写好了,如果读者需要使用并修改功能,就是直接修改mexFunction中的内容即可。更复杂的功能和函数都是可以的。

2. MATLAB端

上面复杂的C++代码都已经写好了,剩下的MATLAB的部分就相对容易了。

使用mexcc编译有一个必要的条件就是安装了VS编译器。

我的配置环境是MATLAB 2011b + VS2010 ultimate + win7-64bit

然后打开MATLAB的 Command Window

输入

mex -setup

0818b9ca8b590ca3270a3433284dd417.png

然后选择选择y

0818b9ca8b590ca3270a3433284dd417.png

选择编译器1

0818b9ca8b590ca3270a3433284dd417.png

再选择y ...

接下来就配置好了的。

接着我们编译刚才写好的ArithmeticOp.cpp文件

在MATLAB中输入

mex ArithmeticOp.cpp

这样就会生成相应的ArithmeticOp.mexw64文件(根据系统位数决定)

然后复制一份.mexw64文件在MATLAB中的工作目录下,就可以正常的在MATLAB Command Window或者.m文件中调用了

0818b9ca8b590ca3270a3433284dd417.png

几点注意事项

1. MATLAB和C++的交互中,接口的调用都是Double型的

2. plhs和prhs使用mxCreateDoubleMatrix()分配的内存是不用回收的,因为接口部分的内存信息是需要传递的

3. 在保持mexFunction()不变的情况下,其他所有的C/C++的功能与特性都是支持的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值