概述
1、为什么我们要用C_MEX 文件
我们知道Matlab擅长处理矩阵运算,提供了很多内建函数以及工具箱,但是对于大量循环的处理效率较低,会出现计算速度的瓶颈,而C对于循环有着高效的处理方式。结合两者特性,我们尝试将耗时的部分改用C实现,由Matalb进行调用。通过使用mex文件,使得Matlab调用C程序与调用内置函数一样简单。
2.、mex文件的组成
C语言MEX 函数主要由计算子程序和接口子程序两个部分组成。
>C和Matlab之间的接口函数(由mexFunction实现)
>用C编写的实现特定功能的计算程序(由用户编写完成特定的功能)
>与平台相关的预处理宏(Windows平台下与C相关的宏,主要与mxArray类相关)
注: 将C/Cpp 文件编译为matlab可以执行的程序,关键是“数据格式的转换”。Matlab中使用的是矩阵类型,一个标量也是使用矩阵进行表述的;而C/CPP中使用的初级类型是int,double等。如何将两类数据调整一致是一个基本问题。
mex文件入口函数:void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]);
mexFunction四个参数的意思为:
nlhs= 1,说明调用语句左手面(lhs-lefthand side)有一个变量,即a。
nrhs= 2,说明调用语句右手面(rhs-righthand side)有两个自变量,即b和c。
plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。
prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
注:因为Matlab最基本的单元为array,无论是什么类型也好,如有double array、 cell array、 struct array……所以a,b,c都是array,b= 1.1便是一个1x1的doublearray。而在C语言中,Matlab的array使用mxArray类型来表示。所以就不难明白为什么plhs和prhs都是指向mxArray类型的指针数组。
function [ z ] = mexAdd( x,y )
%UNTITLED Summary of this function goes here
% Detailed explanation goes here
disp('this is a function.');
z = x+y;
end
现在,我们要用C的方式来实现:
//包含头文件
#include "mex.h"
//C 函数
double mexAdd(double x,double y){
return x+y;
}
//MEX文件的入口函数mexFunction
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]){
double a;
double b;
double *c;
//输入参数、输出参数判断
if(nlhs != 1){
mexErrMsgTxt("One output required!");
}
if(nrhs != 2){
mexErrMsgTxt("Two input required!");
}
//传入的mxArray参数,利用Matlab提供的API函数转成C/C++数据
a = *( mxGetPr(prhs[0]) );
b = *( mxGetPr(prhs[1]) );
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
c = mxGetPr(plhs[0]);
*c = mexAdd(a,b);
}
对于没有配置编译Cmex的首先需要选择配置编译器,如下:
然后就是使用mex命令编译C文件了,编译成功后生成对应的 .mexw64文件或者.mexw32文件,调用时跟普通内建函数使用无区别。
4、数组相加实例
# include "mex.h"
void mexArrayAdd(const int Row,const int Col,const double *A,const double *B,double *C){
int i,j;
for(i=0;i<Row;i++){
for(j=0;j<Col;j++){
//注意数据的表达方式, C语言是按行存储A[i*Col+j],matlab是按列存储 A[i+j*Row]
C[i+j*Row] = A[i+j*Row] + B[i+j*Row];
}
}
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[]){
double *A,*B,*C;
int RowA,ColA,RowB,ColB;
if(nlhs != 1){
mexErrMsgTxt("One output required.");
}
else if(nrhs > 2){
mexErrMsgTxt("Two input required.");
}
if( !mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1]) || mxIsComplex(prhs[0]) || mxIsComplex(prhs[1]) ){
mexErrMsgTxt("Input Array must be double.");
}
//获得矩阵的行数
RowA = mxGetM(prhs[0]);
//获得矩阵的列数
ColA = mxGetN(prhs[0]);
RowB = mxGetM(prhs[1]);
ColB= mxGetN(prhs[1]);
//判断行列是否相等
if(RowA != RowB || ColA != ColB){
mexErrMsgTxt("Rows and Cols must be same.");
}
//获取指向输入参数的指针
A = mxGetPr(prhs[0]);
B = mxGetPr(prhs[1]);
//生成输出参量的mxArray
plhs[0] = mxCreateDoubleMatrix(RowA,ColB,mxREAL);
//获取指向输出参数的指针
C= mxGetPr(plhs[0]);
mexArrayAdd(RowA, ColA, A, B, C);
}
最后
以上就是漂亮野狼为你收集整理的Matab与C混合编程 C_MEX函数编写的全部内容,希望文章能够帮你解决Matab与C混合编程 C_MEX函数编写所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复