想问一下
我有一段C++的程序
如果我要用MATLAB表现这段C++程序
可不可以阿?
要用到点什么东西啊?
现在作毕业设计要用到MATLAB
郁闷了好久
或者有强人加我QQ:82897901
[此贴子已经被作者于2006-5-16 7:34:24编辑过]
C 语言MEX文件源程序的结构
两部分组成:
第一部分称为计算子例程(Computational routine),它包含了所有实际完成计算功能的源代码,用来完成实际的计算工作;
第二部分称为入口子例程(Gateway routine),它是计算子例程同Matlab环境的接口,用来完成两者间的通信任务。
入口子例程的名字为mexFunction,拥有四个参数,分别为prhs,nrhs,plhs和nlhs,其中prhs为一个mxArray结构体类型的指针数组,该数组的数组元素按顺序指向所有的输入参数;nrhs为整型,它标明了输入参数的个数;plhs同样是一个mxArray结构体类型的指针数组,该数组的数组元素按照顺序指向所有的输出参数;nlhs标明了输出参数的个数。
入口子例程的具体格式如下:
void mexFunction(int nlhs,mxArray
*plhs[],int nrhs,const mxArray *prhs[])
{
......
/*一些必要的C语言代码,用来完成Matlab与计算子例程间的通信任务*/
}
在入口子例程中,用户可以完成两个方面的任务:一方面,是从输入的mxArray结构体中获得计算所需要的数据,然后在用户
的计算子例程中加以使用,例如:
例1.C语言MEX的简单例子
#include"mex.h"
void myplus(double y[],double x[],double z[])
{
y[0]=x[0]+z[0];
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,mxArray *prhs[])
{
double *x,*y,*z;
int mrrows0,ncols0;
int mrrows1,ncols1;
if(nrhs!=2)
mexErrMsgTxt("Two inputs
required.");
else
if(nlhs>1)
mexErrMsgTxt("Too
many output arguments!");
mrrows0=mxGetM(prhs[0]);
ncols0=mxGetN(prhs[0]);
if(!mxIsDouble(prhs[0])||mxIsComplex(prhs[0])||!(mrrows0==1&&ncols0==1))\
mexErrMsgTxt("Inputs
must be all noncomplex scalar double.");
mrrows1=mxGetM(prhs[1]);
ncols1=mxGetN(prhs[1]);
if(!mxIsDouble(prhs[1])||mxIsComplex(prhs[1])||!(mrrows1==1&&ncols1==1))\
mexErrMsgTxt("Inputs
must be all noncomplex scalar double.");
if(mrrows0!=mrrows1||ncols0!=ncols1)
mexErrMsgTxt("Input
must be same dimension.");
plhs[0]=mxCreateDoubleMatrix(mrrows0,ncols0,mxREAL);
x=mxGetPr(prhs[0]);
z=mxGetPr(prhs[1]);
y=mxGetPr(plhs[0]);
myplus(y,x,z);
}
例2. C语言MEX对matlab结构体从操作
/* part 1 */
#include "mex.h"
#include <string.h>
#define F_NUM_MAX 3
/*结构体所容许的域的最大值 */
#define S_NUM_MAX 10
/*结构体对象所包含的元素个数的最大值*/
int max=0;
/* part 2 */
void findmax(double *grade[],int n)
{
int i;
for(i=1;i<n;i++)
{
if(*grade[max]<*grade[i])
max=i;
}
return;
}
/*part 3 */
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const
mxArray *prhs[])
{
/*part 4 */
const char
*fnames[F_NUM_MAX];
const int *dims;
mxArray *tmp;
char
*name[S_NUM_MAX];
double
*grade[S_NUM_MAX],*P;
int
i,n,numfields,status,buflen;
/*part 5 */
if(nrhs!=1)
mexErrMsgTxt("One
input required.");
else
if(nlhs>1)
mexErrMsgTxt("Too
many output arguments.");
else if(!mxIsStruct(prhs[0]))
mexErrMsgTxt("Input
must be a structure.");
/*part 6 */
dims=mxGetDimensions(prhs[0]);
numfields=mxGetNumberOfFields(prhs[0]);
n=mxGetNumberOfElements(prhs[0]);
/*part 7 */
for(i=0;i<numfields;i++)
fnames[i]=mxGetFieldNameByNumber(prhs[0],i);
/*part 8 */
for(i=0;i<n;i++)
{
tmp=mxGetField(prhs[0],i,fnames[0]);
if(mxIsChar(tmp)!=1)
mexErrMsgTxt("Element
is not type of string!");
buflen=mxGetN(tmp)*mxGetM(tmp)+1;
name[i]=(char*)mxCalloc(buflen,sizeof(char));
status=mxGetString(tmp,name[i],buflen);
if(status!=0)
mexWarnMsgTxt("Not
enough space.String is truncated.");
tmp=mxGetField(prhs[0],i,fnames[1]);
if(mxIsDouble(tmp)!=1)
mexErrMsgTxt("Element
is not type of double");
grade[i]=mxGetPr(tmp);
}
/*part 9 */
findmax(grade,n);
/*part 10 */
plhs[0]=mxCreateStructMatrix(1,1,numfields,fnames);
tmp=mxCreateString(name[max]);
mxSetField(plhs[0],0,fnames[0],tmp);
tmp=mxCreateDoubleMatrix(1,1,mxREAL);
mxSetPr(tmp,grade[max]);
mxSetField(plhs[0],0,fnames[1],tmp);
return;
}
例3.C 语言MEX文件对matlab单元阵列cell的操作
/* part 1 */
#include "mex.h"
#include <string.h>
void uppercase(char *buf)
{
char * upper;
upper=strupr(buf);
buf=upper;
return;
}
/* part 2 */
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
/*part 3 */
int rows,cols,i,j,count,ndims,nindex;
int buflen,status;
int subs[2];
char * buf;
double *pr,*y;
mxArray *cell_element_pr,*tmp;
/*part 4 */
if(nrhs!=1)
mexErrMsgTxt("Too many output arguments.");
else if(nlhs>1)
mexErrMsgTxt("Too many output arguments.");
else if(!mxIsCell(prhs[0]))
mexErrMsgTxt("Input must be cell.");
ndims=mxGetNumberOfDimensions(prhs[0]);
if(ndims>2)
mexErrMsgTxt("Input must be a cell matrix.");
/* part 5 */
rows=mxGetM(prhs[0]);
cols=mxGetN(prhs[0]);
plhs[0]=mxCreateCellMatrix(rows,cols);
/* part 6 */
for(i=0;i<rows;i++)
{
for(j=0;j<cols;j++)
{
subs[0]=i;
subs[1]=j;
nindex=mxCalcSingleSubscript(prhs[0],2,subs);
cell_element_pr=mxGetCell(prhs[0],nindex);
if(mxIsChar(cell_element_pr))
{
buflen=mxGetM(cell_element_pr)*mxGetN(cell_element_pr)+1;
buf=(char*)mxCalloc(buflen,sizeof(char));
status=mxGetString(cell_element_pr,buf,buflen);
if(status!=0)
mexWarnMsgTxt("Not enough space.String is truncated.");
uppercase(buf);
tmp=mxCreateString(buf);
mxSetCell(plhs[0],nindex,tmp);
mxFree(buf);
}
else
mxSetCell(plhs[0],nindex,mxDuplicateArray(cell_element_pr));
}
}
}
例4. C语言MEX对matlab字符串的操作
#include "mex.h"
#include "matrix.h"
#include <string.h>
void mystringplus(char *input_buf0,char *input_buf1,char *output_buf)
{
strcat(output_buf,input_buf0);
strcat(output_buf,input_buf1);
}
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,mxArray *prhs[])
{
char *input_buf0,*input_buf1,*output_buf;
int buflen,buflen0,buflen1,status;
if(nrhs!=2)
mexErrMsgTxt("Two inputs required.");
else
if(nlhs>1)
mexErrMsgTxt("Too many output arguments!");
/*
if(!mxIsChar(prhs[0])!=1||mxIsChar(prhs[1])!=1)
mexErrMsgTxt("Inputs must be string!");
*/
if(mxGetM(prhs[0])!=1||mxGetM(prhs[1])!=1)
mexErrMsgTxt("Inputs must be a row vector!");
buflen0=(mxGetM(prhs[0])*mxGetN(prhs[0]))+1;
buflen1=(mxGetM(prhs[1])*mxGetN(prhs[1]))+1;
buflen=buflen1+buflen0-1;
input_buf0=(char*)mxCalloc(buflen0,sizeof(char));
input_buf1=(char*)mxCalloc(buflen1,sizeof(char));
output_buf=(char*)mxCalloc(buflen,sizeof(char));
status=mxGetString(prhs[0],input_buf0,buflen0);
if(status!=0)
mexWarnMsgTxt("Not enough space.String is truncated!");
status=mxGetString(prhs[1],input_buf1,buflen1);
if(status!=0)
mexWarnMsgTxt("Not enough space.String is truncated!");
mystringplus(input_buf0,input_buf1,output_buf);
plhs[0]=mxCreateString(output_buf);
return;
}
例5.C语言MEX文件对不同位数据的操作
/* head file */
#include<string.h>
#include<math.h>
#include"mex.h"
/* Macro define */
#define NDIMS 2
#define TOTAL_ELEMENTS 4
/* computational routine */
void mod5(unsigned short *x)
{
unsigned short div=5;
int i;
for(i=0;i<4;i++)
{
*(x+i)=*(x+i)%div;
}
}
/* Gateway routine */
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
/*define variable */
const int dims[]={2,2};
unsigned char *start_of_pr;
unsigned short data[]={56,23,31,47};
int bytes_to_copy;
/* transfer the computational routine */
mod5(data);
/*create an unsigned integer */
plhs[0]=mxCreateNumericArray(NDIMS,dims,mxUINT16_CLASS,mxREAL);
/*Evaluate the Real part of the Array*/
start_of_pr=(unsigned char *)mxGetPr(plhs[0]);
bytes_to_copy=TOTAL_ELEMENTS * mxGetElementSize(plhs[0]);
memcpy(start_of_pr,data,bytes_to_copy);
}
例6. C语言MEX文件对复数的操作
/* head file */
#include "mex.h"
/* computational routine */
void convcc(double * xr,double *xi,int nx,double *yr,double *yi,int ny,double *zr,double *zi)
{
/* initialization variable */
int i,j;
zr[0]=0.0;
zi[0]=0.0;
/* 复数向量的卷积运算 */
for(i=0;i<nx;i++)
{
for(j=0;j<ny;j++)
{
*(zr+i+j)=*(zr+i+j)+*(xr+i)*(*(yr+j))-*(xi+i)*(*(yi+j));
*(zi+i+j)=*(zi+i+j)+*(xr+i)*(*(yi+j))-*(xi+i)*(*(yr+j));
}
}
}
/*Gateway routine */
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
double *xr,*xi,*yr,*yi,*zr,*zi;
int rows,cols,nx,ny;
/*check out the number of input parameter */
if(nrhs!=2)
mexErrMsgTxt("Two input required!");
if(nlhs>1)
mexErrMsgTxt("Too many output arguments.");
/*check out whether the input are vector*/
if(mxGetM(prhs[0])!=1||mxGetM(prhs[1])!=1)
mexErrMsgTxt("Both inputs must be row vectors.");
rows=1;
/*affirm the input are complex numbers */
if(!mxIsComplex(prhs[0])||!mxIsComplex(prhs[1]))
mexErrMsgTxt("Inputs must be complex.\n");
/* get the number of the elements of the inputs */
nx=mxGetN(prhs[0]);
ny=mxGetN(prhs[1]);
/*Get the pointers to the inputs's real and image parts */
xr=mxGetPr(prhs[0]);
xi=mxGetPi(prhs[0]);
yr=mxGetPr(prhs[1]);
yi=mxGetPi(prhs[1]);
/*create the output array */
cols=nx+ny-1;
plhs[0]=mxCreateDoubleMatrix(rows,cols,mxCOMPLEX);
zr=mxGetPr(plhs[0]);
zi=mxGetPi(plhs[0]);
convcc(xr,xi,nx,yr,yi,ny,zr,zi);
return;
}
例7.C语言mex对稀疏矩阵的操作
/* 头文件 */
#include "mex.h"
#include <string.h>
/* 宏定义,用于限制稀疏矩阵的大小及非零元素的个数*/
#define NZMAX 4
#define ROWS 4
#define COLS 2
/* 计算子例程,用于将输入的稀疏矩阵的非零元素加倍*/
void dbl_elem(double elem[],int n)
{
int i;
for(i=0;i<n;i++)
elem[i]=2*elem[i];
return;
}
/* GateWay routine */
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
double *pr_data;
int *ir_data;
int *jc_data;
double *px;
int nz_elem,m,n;
/* Check the number of inputs and outputs*/
if(nrhs!=2)
mexErrMsgTxt("Two inputs required.");
if(nlhs>1)
mexErrMsgTxt("Too many outputs argumented.");
/*检查输入是否为稀疏矩阵*/
if(!mxIsSparse(prhs[0]))
mexErrMsgTxt("Input must be a sparse matrix.\n");
nz_elem=mxGetNzMax(prhs[0]);
if(nz_elem>NZMAX)
mexErrMsgTxt("The nonezeros elements are too much.\n");
m=mxGetM(prhs[0]);
n=mxGetN(prhs[0]);
if(m>ROWS||n>COLS)
mexErrMsgTxt("The sparse matrix is too big.\n");
/*获取输入稀疏矩阵的各种参数*/
pr_data=mxGetPr(prhs[0]);
ir_data=mxGetIr(prhs[0]);
jc_data=mxGetJc(prhs[0]);
dbl_elem(pr_data,nz_elem);
plhs[0]=mxCreateSparse(m,n,nz_elem,mxREAL);
// mxSetName(plhs[0],"Sparse");
px=mxGetPr(plhs[0]);
memcpy((void*)px,(void*)pr_data,nz_elem*sizeof(double));
memcpy((void*)mxGetIr(plhs[0]),(void*)ir_data,nz_elem*sizeof(int));
memcpy((void*)mxGetJc(plhs[0]),(void*)jc_data,nz_elem*sizeof(int));
return;
}