Matlab 调用 c 程序
方法:
第一步:要先在 matlab 中安装 c 程序编译器,步骤如下:
键入命令:mex -setup;
选择 c/c++编译器;
选择 c/c++编译器版本;
确认。
第二步:键入:mex *.c
*******************************************************************************
**************************************************************
实例介绍:【转】
如果我有一个用 C 语言写的函数,实现了一个功能,如一个简单的函数:
double add(double x, double y) {
return x + y;
}
现在我想要在 Matlab 中使用它,比如输入:
>> a = add(1.1, 2.2)
3.3000
要得出以上的结果,那应该怎样做呢?
解决方法之一是要通过使用 MEX 文件,MEX 文件使得调用 C 函数和调用 Matlab 的内置函数
一样方便。MEX 文件是由原 C 代码加上 MEX 文件专用的接口函数后编译而成的。
可以这样理解,MEX 文件实现了一种接口,它把在 Matlab 中调用函数时输入的自变量通过
特定的接口调入了 C 函数,得出的结果再通过该接口调回 Matlab。该特定接口的操作,包
含在 mexFunction 这个函数中,由使用者具体设定。
所以现在我们要写一个包含 add 和 mexFunction 的 C 文件,Matlab 调用函数,把函数中的
自变量(如上例中的 1.1 和 2.2)传给 mexFunction 的一个参数,mexFunction 把该值传给
add,把得出的结果传回给 mexFunction 的另一个参数,Matlab 通过该参数来给出在 Matlab
语句中调用函数时的输出值(如上例中的 a)。
比如该 C 文件已写好,名为 add.c。那么在 Matlab 中,输入:
>> mex add.c
就能把 add.c 编译为 MEX 文件(编译器的设置使用指令 mex -setup),在 Windows 中,MEX
文件类型为 mexw32,即现在我们得出 add.mexw32 文件。现在,我们就可以像调用 M 函数那
样调用 MEX 文件,如上面说到的例子。所以,通过 MEX 文件,使用 C 函数就和使用 M 函数是
一样的了。
我们现在来说 mexFunction 怎样写。
mexFunction 的定义为:
void mexFunction(
int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[]) {
}
可以看到,mexFunction 是没返回值的,它不是通过返回值把结果传回 Matlab 的,而是通
过对参数 plhs 的赋值。mexFunction 的四个参数皆是说明 Matlab 调用 MEX 文件时的具体信
息,如这样调用函数时:
>> b = 1.1; c = 2.2;
>> a = add(b, c)
mexFunction 四个参数的意思为:
nlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即 a。
nrhs = 2,说明调用语句右手面(rhs-right hand 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 的 double array。而在 C
语言中,Matlab 的 array 使用 mxArray 类型来表示。所以就不难明白为什么 plhs 和 prhs
都是指向 mxArray 类型的指针数组。
完整的 add.c 如下:
// add.c
#include "mex.h" // 使用 MEX 文件必须包含的头文件
// 执行具体工作的 C 函数
double add(double x, double y) {
return x + y;
}
// MEX 文件接口函数
void mexFunction(
int nlhs,
mxArray *plhs[],
int nrhs,
const mxArray *prhs[]) {
double *a;
double b, c;
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
a = mxGetPr(plhs[0]);
b = *(mxGetPr(prhs[0]));
c = *(mxGetPr(prhs[1]));
*a = add(b, c);
}
mexFunction 的内容是什么意思呢?我们知道,如果这样调用函数时:
>> output = add(1.1, 2.2);
在未涉及具体的计算时,output 的值是未知的,是未赋值的。所以在具体的程序中,我们
建立一个 1x1 的实 double 矩阵(使用 mxCreateDoubleMatrix 函数,其返回指向刚建立的
mxArray 的指针),然后令 plhs[0]指向它。接着令指针 a 指向 plhs[0]所指向的 mxArray
的第一个元素(使用 mxGetPr 函数,返回指向 mxArray 的首元素的指针)。同样地,我们把
prhs[0]和 prhs[1]所指向的元素(即 1.1 和 2.2)取出来赋给 b 和 c。于是我们可以把 b 和
c 作自变量传给函数 add,得出给果赋给指针 a 所指向的 mxArray 中的元素。因为 a 是指向
plhs[0]所指向的 mxArray 的元素,所以最后作输出时,plhs[0]所指向的 mxArray 赋值给
output,则 output 便是已计算好的结果了。
上面说的一大堆指向这指向那,什么 mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,
要搞清楚这些乱糟糟的关系,只有多看多练。
实际上 mexFunction 是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测
试,以确保
输入正确。如在 add 函数的例子中,用户输入 char array 便是一种错误了。
从上面的讲述中我们总结出,MEX 文件实现了一种接口,把 C 语言中的计算结果适当地返回
给 Matlab 罢了。当我们已经有用 C 编写的大型程序时,大可不必在 Matlab 里重写,只写个
接口,做成 MEX 文件就成了。另外,在 Matlab 程序中的部份计算瓶颈(如循环),可通过
MEX 文件用 C 语言实现,以提高计算速度。
*******************************************************************************
**************************************************************
mex 的目的,
通过 C/C++语言编写代码,在 Matlab 中将其编译成 mex 文件主要可以做以下几方面的事情:
1、加快程序的执行速度. Matlab 在 for 上如老牛拉车的速度确实让人抓狂.
2、将 Matlab 作为 C++的开发调试环境.尤其是有大量数据需要处理时,用 Matlab 观察其中
间结果十分方便.
3、据称可以弥补 Matlab 硬件设备接口的薄弱环节.
今天写了第一个使用 MEX.
一个简单的对 Matlab 普通数值矩阵的操作.
其中 Matlab 规定的与操作系统版本有关的 mwSize,mwIndex, size_t 在 32 位系统上其实本
质上就是 int,所以
一律用 int 代替.
#include "mex.h"
#include
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
int i,j,k;
int index;
double* pr=NULL;
double* pi=NULL;
int M,N;
int ndim;
int dims[2];
for (i=0;i
}
Result:
>>mex test.cpp
>> test(a,b,c)
变量 0:
0.35 0.62 0.83
0.20 0.47 0.59
0.25 0.35 0.55
变量 1:
0.92 0.38 0.53 0.57
0.29 0.57 0.78 0.47
0.76 0.08 0.93 0.01
0.75 0.05 0.13 0.34
变量 2:
0.16+
0.79+
0.31+
0.53+
0.17+
>> help test
本程序用于调试 mx______函数.
0.87j 0.60+
0.08j 0.26+
0.40j 0.65+
0.26j 0.69+
0.80j 0.75+
0.43j 0.45+
0.91j 0.08+
0.18j 0.23+
0.26j 0.91+
0.15j 0.15+
0.14j 0.83+
0.87j 0.54+
0.58j 1.00+
0.55j 0.08+
0.14j 0.44+
0.85j 0.11+
0.62j 0.96+
0.35j 0.00+
0.51j 0.77+
0.40j 0.82+
0.08j
0.24j
0.12j
0.18j
0.24j