Matlab和C混合编程

一、 MEX文件概述

1.1介绍MEX文件

如果想在Matlab中,以Matlab函数的方式调用C程序,那就要用到MEX文件。将C按照一定的格式编写,并编译最终形成MEX文件(后缀为mexw32,不同的Matlab版本这个后缀稍有不同,本文用的是Matlab200b),只要这个MEX文件在Matlab搜索路径中,即可像Matlab工具箱中的函数一样使用了。

1.2 MEX文件的应用

Ø  如果Matlab需要调用已有的C算法,不需要将其翻译成m文件,只需要将其编译成MEX文件即可。

Ø  如果为了性能,必须使用C编写核心代码。

1.3 MEX文件的组成部分

使用mex命令可以将C文件编译成二进制的mex文件。mex将源文件编译和连接成可被调用的动态链接库。一旦将C编译成mex文件后就可以像Matlab工具箱中的函数一样使用。

MEX文件由如下部分组成:

Ø  CMatlab之间的接口函数(mexFunction实现

Ø  C编写的实现特定功能的计算程序(由用户编写完成特定的功能)

Ø  与平台相关的预处理宏(Windows平台下与C相关的宏,主要与mxArray类相关)

1.3.1 CMatlab之间的接口函数

接口函数是MEX文件的入口点,通过接口Matlab才能调用MEX文件,创建入口函数包括如下步骤:

Ø  接口函数签名:

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

Ø  接口参数:

接口必须包括如下参数prhsnrhsplhs,和nlhs详细介绍如下表

参数名称

参数描述

prhs

输入参数

plhs

输出参数

nrhs

输入参数的个数

nlhs

输出参数的个数

Ø  创建使用源文件:

可以将C的源文件和mexFunction入口函数写在一个文件中,也可以将C的源文件和mexFunction分别写成不同的函数。

Ø  使用Matlab库:

Matlab函数库提供了接口函数mexFunctionC计算函数之间的数据转换。

Ø  包含相关头文件

为了使用mexAPI需要包含头文件mex.h

#include "mex.h"

Ø  MEX文件命名

MEX文件名就是被Matlab调用时的函数名,这个名称是包含入口函数的C的源文件名(结果改造的C源文件,已经包括了入口点函数)。

1.3.2 C编写的实现特定功能的计算程序

这部分是原始的未经过改造的C源文件,能够实现用户特定的功能。

1.2.3 预处理宏

mex文件用mwSize代表位数大小,比如矩阵维数大小,数组中元素的个数。

参考实例

Matlab调用C生成的MEX属于异构程序之间的整合,总的来说需要解决两个问题:接口和数据转换(由mxArray实现)。为了清楚解释整个的MEX文件的组成,下面以一个具体而微的例子说明。

假设有如下的C代码,它的功能是输入xy,返回结果在z中,代码如下

void arrayProduct(double x, double *y, double *z, int n)

{    int i;

      for (i=0; i<n; i++)

              z[i] = x * y[i];

}

1 创建mexFunction接口

如果要求Matlab能够调用C代码,就需要将C代码封装到mexFunction入口函数中

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

{

/* 在此声明一些变量,并调用C的代码,所有的工作都在这里*/

}

int nlhs, mxArray *plhs[]:这两个参数描述了输出参数信息,nlhs是输出参数个数,具体的输出参数存放在plhs中。

 nrhs, const mxArray *prhs[]:这两个参数描述了输入参数的信息,nrhs描述输入参数个数,具体的输入参数存放在prhs中。

2 修改C源码

需要将C源码中的数据格式进行调整,如下

void arrayProduct(double x, double *y, double *z, mwSize n)

{  mwSize i;

  for (i=0; i<n; i++)

    z[i] = x * y[i];}

int n需要改为mwSize nmwSize相当于C语言中的int格式。

3 mexFunction中检查输入参数和输出参数(可选)

if(nrhs!=2) { //检查输入参数是否为两个,如果不是两个报错

    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs",

                      "Two inputs required.");

}

if(nlhs!=1) { //检查输出参数是否为一个,如果不是一个报错

    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs",

                      "One output required.");

}

if( !mxIsDouble(prhs[0]) ||  mxIsComplex(prhs[0]) ||  mxGetNumberOfElements(prhs[0])!=1 ) {//检查输入的第一个参数是否为标量

    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notScalar",

                      "Input multiplier must be a scalar.");

}

if(mxGetM(prhs[1])!=1) {//检查输入的第一个参数是否为一维数组

    mexErrMsgIdAndTxt("MyToolbox:arrayProduct:notRowVector",

                      "Input must be a row vector.");

}

4 处理输入参数

为了给void arrayProduct(double x, double *y, double *z, mwSize n)接口传递参数,需要从prhs参数中将每个输入参数取出来,下面的代码需要写在mexFunction接口的开始位置

double multiplier;      /*相当于x*/

double *inMatrix;       /* 相当于y,维数为1xN */

mwSize ncols;           /* 相当于n*/

multiplier = mxGetScalar(prhs[0]);//prhs中获取x

inMatrix = mxGetPr(prhs[1]);//prhs中获取y

ncols = mxGetN(prhs[1]);//prhs中获取n

5 处理输出参数

和处理输入参数类似,对输出参数的处理如下

double *outMatrix;      /* 相当于输出参数z*/

plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);//创建输出参数矩阵

outMatrix = mxGetPr(plhs[0]);//获得输出参数矩阵的指针

6 小结

1.3.1-1.3.5整个过程可以用以下示意图表示为

Matlab和C混合编程_第1张图片

 

注意:以上代码中用到的函数,如mxGetM等的具体功能可以参考Matlab帮助文件,这种函数太多无法一一详细介绍

完整的C源代码,见arrayProduct.c文件。

1.4设置MATLAB来生成MEX文件

1.3中改写好的代码需要编译成MEXMatlab自带默认的Lcc编译器,如果电脑上装有其它的编译器如VS,也可以选用其它的编译器。

Matlab的命令行中输入mex –setup,显示如下结果

Matlab和C混合编程_第2张图片

如果选择y则使用默认的编译器,如果选择n,显示如下图,列出了当前的Matlab支持的外部编译器类型,本文使用Matlab2009VS的版本是2008SP1,所以可以选择8

Matlab和C混合编程_第3张图片

 

下图中的最后一行显示了VS2008SP1的安装位置,如果正确选择y,否则选择n,重新设置VS2008SP1的安装位置,然后按照提示配置完成。

Matlab和C混合编程_第4张图片

 

1.5编译和运行MEX文件

在命令行中输入

mex  arrayProduct.c

编译完成后会生成arrayProduct.mexw32文件,可以像Matlab内置函数一样调用它了。

二、MEX文件的输入输出

2.1 MEX文件中的数据流

以一个例子展示MEX文件的数据流。

2.1.1 数据的输入与输出

假设有MEX文件myFunction,其有两个输入参数和一个输出参数。Matlab的调用方式为x=myFuncntion(y,z)

Matlab用以下参数形式,通过接口函数mexFunction调用myFunction

Matlab和C混合编程_第5张图片

输入是prhs,其含有两个单元的C数组,所以此时nrhs=2prhs的第一个元素是一个指向ymxArray类型的指针,第二个元素是一个指向zmxArray类型的指针。输出是plhs,是一个含有一个单元的C类型数组,所以此时nlhs=1

在接口函数中创建一个输出数组,并将plhs[0]指向它。如果没有设置输出参数,而在调用的时候有返回参数,此时Matlab将会报错。

2.1.2 接口函数mexFunction中的数据流

在下面这个例子中,调用的MEX文件为[C,D]=func(A,B)。当在Matlab中调用时,Matlab将输入参数AB传递给MEX文件,CD是返回参数。

func.c中,首先使用mxCreate*函数(meArrayAPI函数)创建输出参数,然后用plhs[0]plhs[1]指向创建的输出参数;使用mxGet*函数从输入参数prhs[0]prhs[1]中获取输入参数。最后调用真正完成特定功能的计算程序计算,并将相应的输入和输出指针传递给该计算程序。

Matlab和C混合编程_第6张图片

2.2 MATLAB 数据

Matlab数据包括:标量数据,向量数据,矩阵数据,字符串数据,元包数据,结构体,对象。这些数据在Matlab中都是以数组形式存储的。在CMatlab数组用mxArray表示。

2.3 mxArray class

要想在Matlab中调用C编译成的MEX文件,需要将Matlab的数据格式转化为C的数据格式。在Matlab中使用mxArray完成这种转化,通过能够通过mxArray类获取Matlab中的数据结构类型,其获取的信息如下

Ø  数据类型

Ø  数据维数

Ø  数据本身

Ø  如果是浮点型的,那么是浮点型的复数还是实数

Ø  如果是稀疏数据,数据的索引和数据值

Ø  如果是结构体或对象,域的个数或者域名是什么

以上的这些信息都是通过mxArray类中的API完成的,在下面的2.5中将会介绍常用的API

2.4 使用指针

通过指针完成输入和输出参数的传递,例子如下

inMatrix = mxGetPr(prhs[1]);//获得prhs[1]的指针,作为输入参数

plhs[0] = mxCreateDoubleMatrix(1,ncols,mxREAL);//创建一维数组作为输出

outMatrix = mxGetPr(plhs[0]);//获得输出函数额指针

2.5 使用mxArray API 函数

本节将介绍mxArray中常用的API

2.5.1 判断数据类型的mxArray方法

bool mxIsDouble(const mxArray *pm);//如果pm是浮点型返回true

bool mxIsInf(double value);//如果value为无穷大返回true

2.5.2 获取数据维度

size_t mxGetM(const mxArray *pm);//获得pm的行数

size_t mxGetN(const mxArray *pm);//获得pm的列数

size_t mxGetNumberOfElements(const mxArray *pm);//获得pm中元素的个数

2.5.3 获取数据本身

通过指针获取数据,见2.4

2.6 使用字符串

mxArray *mxCreateString(const char *str);

2.7 何时使用MEX文件

1.2

2.8 处理数据

在这部分,将举例说明如何处理二位数组,字符串如何使用。

三、 MEX文件界面

2.1 显示诊断信息

在使用MEX文件时可能有些错误信息显示出来,需要用户了解产生这些错误信息的原因,概括如下:

2.1.1 MEX存在平台版本问题

如果运行MEXMatlab版本和编译它的版本不一致时会导致错误信息,如下

??? Invalid MEX-file <mexfilename>:

The specified module could not be found.

2.2.2 Matlab所支持的编译器版本

不同的Matlab会支持不同的编译器版本,如果编译器选择的不对会造成编译错误。

2.2.3 编写的C源代码是否为ANSI C编写

 

如果C代码中的语法不是标准C也可能产生问题。

2.2.4 mexFunction接口错误造成的编译错误

如果显示如下错误可能是mexFunction入口函数拼写错误造成的,导致找不到入口的错误

Unable to load mex file:

??? Invalid MEX-file

2.2.5 总线错误

MEX文件访问被保护、只读或者未被分配的内存区域时会报错。而这种错误却很难被发现。

可以通过以下错误减少这种错误的发生

Ø  重新编译MEX文件,并加上参数检查功能。在编译的时候使用mex的脚本编译选项-argcheck选项,当再有问题时系统将会给出警告。

Ø  debug下进行调试。

2.2.6 计算结果错误

当计算结果错误时,可能是计算程序逻辑错误,或者是某些变量没有初始化。

可能产生错误信息的地方如下图

Matlab和C混合编程_第7张图片

2.2 内存分配

MEX文件中如果需要动态分配内存可以用如下的mexArrayAPI

mwPointer mxCalloc(n, size)

void *mxMalloc(mwSize n);

mwPointer mxRealloc(ptr, size)

2.3 防止内存泄漏

MEX文件调用完成后,除了plhs[]参数列表相关内存保留外,所有的MEX文件内部动态分布的内存都自动清除,包括在2.2中用到的内存分配的方法。

一般来说还是推荐用户删除开辟的动态内存,而不是靠系统自动删除动态开辟的内存。

不过如下情况必须考系统自动回收内存(用户不能显示回收)

Ø  输入参数prhs[]内存

Ø  输出参数plhs[]内存

Ø  通过函数mexGetVariablePtr获得的指针

Ø  创建的结构体

2.3.1 错误的使用回收内存函数

不能用mxFree回收mxArray内存空间,而应该使用如下的方式回收

mxArray *temp = mxCreateDoubleMatrix(1,1,mxREAL);

mxFree(temp);  /* 错误 */

mxDestroyArray(temp);  /*正确 */

因为mxFree删除的是数据结构的头指针,存储数据的空间不会被删除,当退出MEX文件时Matlab还会自动回收临时变量的空间所以还会再一次自动删除temp的指针,这样就会发生错误。

2.3.2 错误的使用赋值函数导致内存回收失败

下面的例子将会产生奇怪的错误,因为在MEX文件被调用完成后,其内部除了输入、输出参没有被Matlab自动销毁外,其它临时变量都是由Matlab自动回收内存的。下面的代码首先创建一个mxArray类型的数组,然后将输入参数prhs[0]的值拷贝给temp这会导致问题,因为MEX文件调用结束后temp将被自动回收,那么prhs将被删除;而之前一再强调prhs的参数是不能被Matlab自动回收的。

mxArray *temp = mxCreateCellMatrix(1,1);

mxSetCell(temp, 0, prhs[0]);  /* 错误 */

所以正确的做法是如下,将prhs做一份拷贝操作

mxSetCell(temp, 0, mxDuplicateArray(prhs[0]));  /* 正确 */

2.3.3 错误使用数据导致内存报错

下面的例子先创建一个空的mxREAL类型的数组temp,然后将double型的数组中元素拷贝给temp,会出现错误,因为mxSetPr要求data必须是用mxCallocmxMallocmxRealloc动态开辟的

mxArray *temp = mxCreateDoubleMatrix(0,0,mxREAL);

double data[5] = {1,2,3,4,5};

      ...

mxSetM(temp,1); mxSetN(temp,5); mxSetPr(temp, data); /* 错误 */

所以需要改成如下方式,用memcpy方法实现

mxArray *temp = mxCreateDoubleMatrix(1,5,mxREAL);

double data[5] = {1,2,3,4,5};

      ...

memcpy(mxGetPr(temp), data, 5*sizeof(double)); /* 正确 */

2.3.4 防止内存泄露

下面情况会造成内存泄露,泄露空间大小为5*5*8字节,因为double8个字节。

pr = mxCalloc(5*5, sizeof(double));

... <load data into pr>

plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL);

mxSetPr(plhs[0], pr);  /* INCORRECT */

改造的方法如下

plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL);

pr = mxGetPr(plhs[0]);

... <load data into pr>

或者

pr = mxCalloc(5*5, sizeof(double));

... <load data into pr>

plhs[0] = mxCreateDoubleMatrix(5,5,mxREAL);

mxFree(mxGetPr(plhs[0]));

mxSetPr(plhs[0], pr);

2.4 处理输入输出内存

输入内存和输出内存的处理由系统控制,即使MEX文件别调用结束后输入输出内存也是存在的,用户不要动态的回收输入和输出内存,也不能由于某些错误操作,误回收输入输出内存。

例如在2.3.2mxSetCell(temp, 0, prhs[0]);  /* 错误 */就会导致在MEX文件别调用结束后prhs自动回收,这就会导致问题,所以要注意。

2.3.4中显示了输出内存处理不当会造成内存泄露。

2.5 调试 MEX文件

见演示

三、 C代码中调用MATLAB

4.1 介绍MATLAB engine

所谓Matlab引擎(engine),是指一组Matlab提供的接口函数,支持C/C++Fortran等语言,通过这些接口函数,用户可以在其它编程环境中实现对Matlab的控制。可以主要功能有:

Ø  打开/关闭一个Matlab对话。

Ø  Matlab环境发送命令字符串。

Ø  Matlab环境中读取数据。

Ø  Matlab环境中写入数据。

与其它各种接口相比,引擎所提供的Matlab功能支持是最全面的。通过引擎方式,应用程序会打开一个新的Matlab进程,可以控制它完成任何计算和绘图操作。对所有的数据结构提供100%的支持。同时,引擎方式打开的Matlab进程会在任务栏显示自己的图标,打开该窗口,可以观察主程序通过engine方式控制Matlab运行的流程,并可在其中输入任何Matlab命令。

4.2 MATLAB engine应用中的数据流

数据流主要包括如下

1、启动Matlab引擎

2、将C环境下的数据送入Matlab工作空间

3、将要执行的Matlab脚本送入Matlab空间并执行

4、从Matlab空间中取回结算结果

5、关闭Matlab引擎。

4.3 调用MATLAB engine

4.3.1 引擎环境配置

要在C中成功编译Matlab引擎程序,必须完成如下配置

Ø  在编译器中包含引擎头文件engine.h所在的路径

Ø  在编译器中加入Matlab对应的依赖库文件libmx.liblibmat.liblibeng.lib,并加入以上库文件所在的路径

Ø  path路径中加入libeng.dll动态链接库文件所在的路径(切记否则编译可以通过运行会出错)

4.3.2 引擎API详解

在调用Matlab引擎之前,首先应在相关文件中加入一行:#include "enging.h",该文件包含了引擎API函数的说明和所需数据结构的定义。可以在C中调用的引擎函数分别如下:

1 引擎的打开和关闭

engOpen-打开Matlab engine

函数声明:

Engine *engOpen(const char *startcmd);

参数startcmd是用来启动Matlab引擎的字符串参数,在Windows操作系统中只能为NULL

函数返回值是一个Engine类型的指针,它是在engine.h中定义的engine数据结构。

  engClose-关闭Matlab 引擎

函数声明:

int engClose(Engine *ep);

参数ep代表要被关闭的引擎指针。

函数返回值为0表示关闭成功,返回1表示发生错误。

例如,通常用来打开/关闭Matlab引擎的代码如下:

Engine *ep; //定义Matlab引擎指针。

if (!(ep=engOpen(NULL))) //测试是否启动Matlab引擎成功。

{

MessageBox("Can't start Matlab engine!" );

exit(1);

}

. …………

engClose(ep); //关闭Matlab引擎。

2 Matlab发送命令字符串

engEvalString-发送命令让Matlab执行。

函数声明:

int engEvalString(Engine *ep, Const char *string);

参数ep为函数engOpen返回的引擎指针,字符串string为要matlab执行的命令。

函数返回值为0表示成功执行,返回1说明执行失败(如命令不能被Matlab正确解释或Matlab引擎已经关闭了)。

3 获取Matlab命令窗口的输出

要在C中获得函数engEvalString发送的命令字符串被Matlab执行后在matlab窗口中的输出,可以调用engOUtputBuffer函数。

函数声明:

int engOutputBuffer(Engine *ep, char *p, int n);

参数epMatlab引擎指针,p为用来保存输出结构的缓冲区,n为最大保存的字符个数,通常就是缓冲区p的大小。该函数执行后,接下来的engEvalString函数所引起的命令行输出结果会在缓冲区p中保存。如果要停止保存,只需调用代码:engOutputBuffer(ep, NULL, 0)

4 读写Matlab数据

4.1Matlab引擎工作空间中获取变量。

mxArray *engGetVariable(Engine *ep, const char *name);

参数ep为打开的Matlab引擎指针,name为以字符串形式指定的数组名。

函数返回值是指向name数组的指针,类型为mxArray*mxArray数据类型在本文第4节详细简介)

4.2 Matlab引擎工作空间写入变量。

int engPutVariable(Engine *ep, const char *name, const mxArray *mp);

参数ep为打开的Matlab引擎指针,mp为指向被写入变量的指针,name为变量写入后在Matlab引擎工作空间中的变量名。

函数返回值为0表示写入变量成功,返回值为1表示发生错误。

5 调用引擎时显示/隐藏Matlab主窗口

默认情况下,以engine方式调用Matlab的时候,会打开Matlab主窗口,可在其中随意操作。但有时也会干扰应用程序的运行,可用以下设置是否显示该窗口。

int engSetVisible(Engine *ep, bool value);

参数ep为打开的Matlab引擎指针,value为是否显示的标志,取值true(或1)表示显示Matlab窗口,取值false(或0)表示隐藏Matlab窗口。

函数返回值为0表示设置成功,为1表示有错误发生。

要获得当前Matlab窗口的显示/隐藏情况,可以调用函数:

int engGetVisible(Engine *ep, bool *value);

参数ep为打开的Matlab引擎指针,Value为用来保存显示/隐藏情况的变量(采用指针方式传递)。

函数返回值为0表示获取成功,为1表示有错误发生。

 

 

参考:数据类型mxArray的操作

  Matlab引擎函数中,所有与变量有关的数据类型都是mxArray类型。数据结构mxArray以及大量的mx开头的函数,广泛用于Matlab 引擎程序和Matlab C数学库中。mxArray是一种很复杂的数据结构,与Matlab中的array相对应,我们只需熟悉Matlabarray类型和几个常用的mxArray函数即可。

C中,所有和Matlab的数据交互都是通过mxArray来实现的,在使用mxArray类型的程序中,应包含头文件matrix.h,不过在引擎程序中,一般会包含头文件engine.h,该文件里面已经包含了matrix.h,因此无需重复包含。

1 创建和清除mxArray型数据

Matlab有很多种变量类型,对应于每种类型,基本上都有一个函数用于创建,但它们都有相同的数据结构,就是mxArray

数组的建立采用mxCreatexxx形式的函数,例如新建一个double类型数组,可用函数mxCreateDoubleMatrix,函数形式如下:

mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity ComplexFlag);

参数mn为矩阵的函数和列数。ComplexFlag为常数,用来区分矩阵中元素是实数还是复数,取值分别为mxREALmxCOMPLEX

例如,创建一个35列的二维实数数组,可用如下语句:

mxArray *T = mxCreateDoubleMatrix(3, 5, mxREAL);

对应的,要删除一个数组mxDestroyArray,该函数声明如下:

void mxDestroyArray(mxArray *array_ptr);

参数array_ptr为要删除的数组指针。

例如,要删除上面创建的数组T,可用如下语句:

mxDestroyArray(T);

类似的创建函数还有:

mxArray *mxCreateString(const char *str);

创建一个字符串类型并初始化为str字符串。

一般的在VCMatlab交互中,以上两种类型就够了,其它类型数组的创建这里不再介绍。

2 管理mxArray数据类型

2.1 管理mxArray数据大小

要获得mxArray数组每一维上元素的个数,可以用mxGetMmxGetN函数。其中mxGetM用来获得数组第一维的元素个数,对于矩阵来说就是行数。

int mxGetM(const mxArray *array_ptr); //返回array_ptr对应数组第一维的元素个数(行数)

int mxGetN(const mxArray *array_ptr); //返回array_ptr对应数组其它维的元素个数,对于矩阵来说是列数。对于多维数组来说是从第2维到最后一维的各维元素个数的乘积。

要获得某一特定维的元素个数,则要用函数:

const int *mxGetDimensions(const mxArray *array_ptr);

该函数返回array_ptr各维的元素个数保存在一个int数组中返回。对于常用的矩阵来说,用mxGetMmxGetN两个函数就可以了。

另外还可以通过mxGetNumberOfDimensions来获得数组的总的维数,用mxSetMmxSetN设置矩阵的行数和列数,函数说明如下:

int mxGetNumberOfDimensions(const mxArray *array_ptr); //返回数组的维数

void mxSetM(mxArray *array_ptr, int m); //设置数组为m

void mxSetN(mxArray *array_ptr, int n); //设置数组为n

  2.2 判断mxArray数组类型

在对mxArray类型的变量进行操作之前,可以验证以下其中的数组的数据类型,比如是否为double数组、整数、字符串、逻辑值等,以及是否为某种结构、类、或者是特殊类型,比如是否为空数组,是否为infNaN等。常见的判断函数有:

bool mxIsDouble(const mxArray *array_ptr);

bool mxIsComplex(const mxArray *array_ptr);

bool mxIsChar(const mxArray *array_ptr);

bool mxIsEmpty(const mxArray *array_ptr);

bool mxIsInf(double value);

2.3 管理mxArray数组的数据

对于常用的double类型的数组,可以用mxGetPrmxGetPi两个函数分别获得其实部和虚部的数据指针,这两个函数的声明如下:

double *mxGetPr(const mxArray *array_ptr); //返回数组array_ptr的实部指针

double *mxGetPi(const mxArray *array_ptr); //返回数组array_ptr的虚部指针

这样,就可以通过获得的指针对mxArray类型的数组中的数据进行读写操作。例如可以用函数engGetVariableMatlab工作空间读入mxArray类型的数组,然后用mxGetPrmxGetPi获得数据指针,对并其中的数据进行处理,最后调用engPutVariable函数将修改后的数组重新写入到Matlab工作空间。

4.3.3 调用实例

1直接在通过字符串执行脚本

 

2通过函数名执行脚本

4.4 编译和运行MATLAB engine 程序

这部分的功能是将调用Matlab引擎的C源代码编译成可执行程序

以下命令会将mexfilename.c编译成mexfilename.exe文件,具体执行见演示。

mex('-f', [matlabroot ...

   '\bin\win32\mexopts\lccengmatopts.bat'], mexfilename);

【注意:在执行编译后的mexfilename.exe程序时可能会报告无法找到lib*.dll库文件,需要将matlabroot\bin\win32加入到path路径中,这样系统才能找到需要执行的库文件。】

 

 

你可能感兴趣的:(Matlab和C混合编程)