Matlab与C++混合编程--多接口+回调函数

Matlab与C++混合编程–多接口+回调函数



一、环境配置

本案例采用MatLab R2014a + Visual Studio 2015。
在matlab命令行中输入mex -setup,查看可以运行的C++编译器或SDK,如果没有安装任何编译器或者SDK则找不到任何编译器。安装编译器或SDK可以参考博客 https://blog.csdn.net/qq_17783559/article/details/82017379。

二、利用C++编写mex库

1.工程属性配置

在VS中创建动态库工程mexTest。

工程属性配置:
目标文件扩展名:.mexw64
包含D:\Program Files\MATLAB\R2014a\extern\include,
依赖D:\Program Files\MATLAB\R2014a\extern\lib\win64\microsoft,
链接库libmex.lib;libeng.lib;libmx.lib;libmat.lib。上述目录是我的matlab安装路径。

编译后生成mexTest.mexw64文件。

2.mexFunction

mexFunction相当于C/C++中main函数,一个mex动态库仅能包含一个mexFunction函数。本次案例中,通过mexFunction调用多个函数,根据函数名称确定要调用的函数,例如add、mutiple、count、callback(回调函数)。利用这种方式能够实现多接口调用。
代码如下(示例):

// nlhs: 函数左侧,输出参数数目   (Left-hand side)
// plhs: 函数左侧,指向输出参数的指针 
// nrhs: 函数右侧,输入参数数目
// prhs: 函数右侧,指向输入参数的指针
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	/*if (nlhs != 2 || nrhs != 3) {
		mexPrintf("Parameter number err.\n");
		return;
	}*/

	std::string name = mxArrayToString(prhs[0]);
	double a = *((double*)mxGetPr(prhs[1]));
	double b = *((double*)mxGetPr(prhs[2]));

	mexPrintf("name: %s\n",name);

	plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
	double* out = (double*)mxGetPr(plhs[0]);

	char str[128];
	std::strcpy(str, "adadafgfgfghkmnop");
	plhs[1] = mxCreateString(str);
	
	if (name == "add")
		*out = add(a, b);
	else if (name == "mutiple")
		*out = mutiple(a, b);
	else if(name=="count")
		*out = count();
	else if (name == "callback")
	{
		callback(nlhs, plhs, nrhs, prhs);
	}
	else
		*out = 10000000000;
}

3.具体函数实现

add、mutiple、count、callback函数代码如下。callback函数循环十次,调用matlab的myfunc函数。回调函数可参考博客https://blog.csdn.net/tianwenzhe00/article/details/32692255。
回调函数方案:MATLAB调用C文件,再在C文件中调用MATLAB函数(即mex文件中调用matlab函数)。在MEX 文件中添加mexCallMATLAB函数,可实现调用MATLAB函数、用户自定义函数以及MEX函数。mexCallMATLAB通过函数名进行调用。

#include "mex.h"
#include "mexTest.h"
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

int cnt = 0;
int w = 4, h = 3, bits = 10;
double *img;

double add(double a, double b) {
	return a + b;
}

double mutiple(double a, double b) {
	return a * b;
}

double count() {
	return cnt += 1;
}

void callback(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	for (int i = 0; i < 10; i++) {
		prhs[1] = mxCreateDoubleMatrix(1, w*h, mxREAL);
		double* img = (double*)mxGetPr(prhs[1]);
		for (int m = 0; m < h; m++) {
			for (int n = 0; n < w; n++) {
				img[m*w + n] = m + n + i;
			}
		}
		
		*((double*)mxGetPr(prhs[2])) = w;
		*((double*)mxGetPr(prhs[3])) = h;
		*((double*)mxGetPr(prhs[4])) = bits;

		mexCallMATLAB(nlhs, (mxArray**)(&plhs[0]), nrhs - 1, (mxArray**)(&prhs[1]), "myfunc");
	}
}

4.模块定义文件

在动态库模块定义文件中增加mexFunction函数导出。
代码如下(示例):

LIBRARY "mexTest"
EXPORTS
	mexFunction

三、在MatLab中调用mex文件

通过VS编译生成mexTest.mexw64,将该文件复制到MatLab代码运行目录下。

1.test.m

mexTest.mexw64可直接调用,mexTest作为函数名,代码如下所示。

mexTest第一个参数是函数名,指明要调用的函数。后面的参数要根据具体的函数进行变化,例如函数double add(double a, double b)包含两个浮点数参数。

mexTest(‘callback’, 1.0,3.0,3.0,10.0)后面的参数是根据回调函数myfunc.m确定的。参数值可以任意给定,因为在mex库中将重新创建。

[data,str]=mexTest('add', 12.5, 45.6);
[data0,str]=mexTest('mutiple', 12.5, 45.6);

for i=1:11
    [data1,str]=mexTest('count', 12.5, 45.6);
end

mexTest('callback', 1.0,3.0,3.0,10.0);

1.编写myfunc.m

function myfunc(img,w,h,bits)
    for i=1:w*h
        fprintf('%0.0f  ',img(i));
    end
    fprintf('\n');
end

总结

该文章主要记录Matlab调用mex库使用方法。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值