、 主 要 函 数 举 例 :
· MATFile *matOpen(const char *filename, const char * mode)— — 打 开 /创 建
· MATFile *matOpen(const char *filename, const char * mode)— — 打 开 /创 建 一 个 MAT文 件 ;
· int matClose(MATFile *pMF)— — 关 闭 一 个 MAT文 件 ;
· mxArray *mxCreateDoubleMatrix(int m, int n, mxComplexity flag)
— — 创 建 一 个 ( 复 ) 双 精 度 矩 阵 ;
· mxArray *mxCreateSparse(int m, int n, int nzmax, mxComplexity flag)
— — 创 建 一 个 稀 疏 矩 阵 ;
· mxArray *matGetNextArray(MATFile *pMF)— — 获 得 MAT文 件 里 面 下 一 个 矩 阵 ;
· const char *mxGetName(const mxArray *pa)— — 获 得 矩 阵 pa的 名 称 ;
· void mxSetName(mxArray *pa,const char *s)— — 为 矩 阵 pa设 置 一 个 名 称 ;
· int mxGetM(const mxArray *pa)— — 获 得 矩 阵 pa的 总 行 数 ;
· int mxGetN(const mxArray *pa)— — 获 得 矩 阵 pa的 总 列 数 ;
· double *mxGetPr(const mxArray *pa)— — 获 得 矩 阵 pa的 pr指 针 ;
· int *mxGetIr(const mxArray *pa)— — 获 得 稀 疏 矩 阵 pa的 ir指 针 ;
· int *mxGetJc(const mxArray *pa)— — 获 得 稀 疏 矩 阵 pa的 jc指 针 ;
· int matPutArray(MATFile * pMF, const mxArray * pA)
— — 把 矩 阵 pA存 储 入 MAT文 件 pMAF;
· void mxDestroyArray(mxArray *pa)— — 释 放 矩 阵 pa( 把 它 从 内 存 中 撤 销 ) ;
5、 两 个 例 子 :
· 获 取 一 个 MAT文 件 中 第 一 个 矩 阵 的 信 息
· 获 取 一 个 MAT文 件 中 第 一 个 矩 阵 的 信 息
typedef struct {
char szFileName[256];
MATFile* pMatFile;
mxArray* pArray;
char szArrayName[64];
char szErrMsg[256];
unsigned int nArrayDim[2];
bool bIsSparse;
} MATFileStruct;
int GetMATFileStruct(MATFileStruct *pMAThdr)
{
if((pMAThdr->pMatFile=matOpen(pMAThdr->szFileName,"r"))==NULL)
{ strcpy(pMAThdr->szErrMsg,"Can't open this mat file");
return(0);
}/*打 开 一 个 MAT文 件 */
if((pMAThdr->pArray=matGetNextArray(pMAThdr->pMatFile))==NULL)
{ strcpy(pMAThdr->szErrMsg,"Can't get arrays");
matClose(pMAThdr->pMatFile);
return(0);
}/*获 取 MAT文 件 中 的 第 一 个 矩 阵 */
}/*获 取 MAT文 件 中 的 第 一 个 矩 阵 */
pMAThdr->nArrayDim[0]=mxGetM(pMAThdr->pArray); /*获 取 其 行 数 */
pMAThdr->nArrayDim[1]=mxGetN(pMAThdr->pArray); /*获 取 其 列 数 */
strcpy(pMAThdr->szArrayName,mxGetName(pMAThdr->pArray)); /*获 取 其 名 称 */
pMAThdr->bIsSparse=mxIsSparse(pMAThdr->pArray); /*判 断 它 是 否 是 系 数 矩 阵 */
mxDestroyArray(pMAThdr->pArray); /*在 内 存 中 撤 销 这 个 矩 阵 */
matClose(pMAThdr->pMatFile); /*关 闭 MAT文 件 */
return(1);
}
· 创 建 稀 疏 矩 阵 并 赋 值
int i,j,k,m,n,nzmax,*ir,*jc;
double *pr;
unsigned short *pData;
mxArray *pa; file://初 始 化 。
m=pLCMShdr->TrueHdr.nArrayDim[0]; file://获 得 原 矩 阵 行 数 。
n=pLCMShdr->TrueHdr.nArrayDim[1]; file://获 得 原 矩 阵 列 数 。
nzmax=0;
for(i=0;i<m*n;i++)
{ if(pData!=0)
nzmax++;
nzmax++;
} file://计 算 数 据 中 非 零 元 个 数 。
if(nzmax<n)
nzmax=n;
pa=mxCreateSparse(m,n,nzmax,mxREAL); /*创 建 一 个 空 的 稀 疏 矩 阵 pa。 */
mxSetName(pa,pLCMShdr->TrueHdr.szArrayName); /*为 稀 疏 矩 阵 pa设 置 名 称 。 */
pr=mxGetPr(pa); file://获 得 pa的 pr指 针 。
ir=mxGetIr(pa); file://获 得 pa的 ir指 针 。
jc=mxGetJc(pa); file://获 得 pa的 jc指 针 。
k=0;
for(j=0;j<n;j++)
{ jc[j]=k; file://jc[j]: 截 至 到 第 j列 非 零 元 的 个 数 。
for(i=0;i { if(pData!=0) file://如 果 第 j列 第 i行 的 元 素 是 个 非 零 元 。
{ ir[k]=i; file://记 录 下 第 k个 非 零 元 的 行 号 。
k++;
}
}
pData+=m; file://移 动 pData指 针 到 下 一 列 。
}
jc[n]=k; file://jc[n]等 于 矩 阵 中 非 零 元 的 个 数 。
matPutArray(pmat,pa); file://把 稀 疏 矩 阵 pa存 入 MAT文 件 pmat。
mxDestroyArray(pa); file://从 内 存 中 撤 销 矩 阵 pa。
( 五 ) 引 擎 应 用 程 序
1、 简 介
引 擎 应 用 程 序 的 实 质 是 把 MATLAB做 为 一 个 引 擎 , 它 允 许 从 你 自 己 的 C++程 序 调 用 这 个 引 擎 。 在 运 行 时 , 引 擎 作 为 一 个 进 程 单 独 运 行 , 你 的 C++程 序 也 作 为 一 个 进 程 单 独 运 行 , 二 者 可 以 通 过 进 程 间 的 通 信 机 制 进 行 交 互 。
2、 引 擎 库
MATLAB引 擎 库 包 含 了 若 干 个 控 制 MATLAB引 擎 的 函 数 , 如 下 所 示 :
engOpen 启 动 MATLAB引 擎
engClose 关 闭 MATLAB引 擎
engGetArray 从 MATLAB引 擎 中 获 取 一 个 MATLAB矩 阵
engPutArray 向 MATLAB引 擎 发 送 一 个 MATLAB矩 阵
engEvalString 执 行 于 一 个 MATLAB命 令
engOutputBuffer 创 建 一 个 存 储 MATLAB文 本 输 出 的 缓 冲 区
同 时 , 引 擎 应 用 程 序 还 可 以 使 用 前 面 提 到 的 API函 数 。
3、 一 个 例 子
从 这 个 示 例 中 , 我 们 看 出 引 擎 应 用 程 序 是 如 何 编 制 的 :
/* $Revision: 1.3 $ */
/*
* engdemo.c
*
* This is a simple program that illustrates how to call the
* MATLAB engine functions from a C program.
*
* Copyright (c) 1996-1998 The MathWorks, Inc.
* All rights reserved
*/
#include
#include
#include
#include "engine.h"
#define BUFSIZE 256
int main()
{
Engine *ep;
mxArray *T = NULL, *result = NULL;
char buffer[BUFSIZE];
double time[10] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0,
8.0, 9.0 };
8.0, 9.0 };
6-6
/*
* Start the MATLAB engine locally by executing the string
* "matlab".
*
* To start the session on a remote host, use the name of
* the host as the string rather than \0
*
* For more complicated cases, use any string with whitespace,
* and that string will be executed literally to start MATLAB.
*/
if (!(ep = engOpen("\0"))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
return EXIT_FAILURE;
} /*启 动 MATLAB引 擎 */
/*
* PART I
*
* For the first half of this demonstration, we will send data
* to MATLAB, analyze the data, and plot the result.
*/
/*
/*
* Create a variable for our data.
*/
T = mxCreateDoubleMatrix(1, 10, mxREAL); /*创 建 一 个 矩 阵 */
mxSetName(T, "T"); /*设 置 矩 阵 的 名 字 为 “ T” */
memcpy((void *)mxGetPr(T), (void *)time, sizeof(time)); /*向 矩 阵 “ T” 赋 值 */
/*
* 把 矩 阵 “ T” 置 入 MATLAB引 擎
*/
engPutArray(ep, T)
/*
* Evaluate a function of time, distance = (1/2)g.*t.^2
* (g is the acceleration due to gravity).
*/
engEvalString(ep, "D = .5.*(– 9.8).*T.^2;"); /*执 行 MATLAB
命 令 : D = .5.*(– 9.8).*T.^2; */
/*
* 绘 制 图 象 .
*/
engEvalString(ep, "plot(T,D);"); /*执 行 MATLAB命 令 : 绘 图 */
engEvalString(ep, "title('Position vs. Time for a falling
object');"); /*执 行 MATLAB命 令 : 给 图 象 加 标 题 */
engEvalString(ep, "xlabel('Time (seconds)');"); /*执 行 MATLAB命 令 : 设 置 X轴 坐 标 */
engEvalString(ep, "xlabel('Time (seconds)');"); /*执 行 MATLAB命 令 : 设 置 X轴 坐 标 */
engEvalString(ep, "ylabel('Position (meters)');"); /*执 行 MATLAB命 令 : 设 置 Y轴
坐 标 */
/*
* Use fgetc() to make sure that we pause long enough to be
* able to see the plot.
*/
printf("Hit return to continue\n\n");
fgetc(stdin);
/*
* We're done for Part I! Free memory, close MATLAB engine.
*/
printf("Done for Part I.\n");
mxDestroyArray(T); /*从 内 存 中 撤 销 矩 阵 “ T” */
engEvalString(ep, "close;"); /*关 闭 刚 才 显 示 图 象 的 窗 口 */
/*
* PART II
*
* For the second half of this demonstration, we will request
* a MATLAB string, which should define a variable X. MATLAB
* will evaluate the string and create the variable. We
* will then recover the variable, and determine its type.
*/
*/
/*
* Use engOutputBuffer to capture MATLAB output, so we can
* echo it back.
*/
engOutputBuffer(ep, buffer, BUFSIZE); /*构 建 MATLAB文 本 输 入 缓 冲 区 */
while (result == NULL) {
char str[BUFSIZE];
/*
* Get a string input from the user.
*/
printf("Enter a MATLAB command to evaluate. This
command should\n");
printf("create a variable X. This program will then
determine\n");
printf("what kind of variable you created.\n");
printf("For example: X = 1:5\n");
printf(">> "); /*要 求 用 户 输 入 一 个 MATLAB命 令 */
fgets(str, BUFSIZE– 1, stdin); /*获 得 用 户 输 入 */
/*
* Evaluate input with engEvalString.
*/
engEvalString(ep, str); /*执 行 用 户 输 入 的 MATLAB命 令 */
engEvalString(ep, str); /*执 行 用 户 输 入 的 MATLAB命 令 */
/*
* Echo the output from the command. First two characters
* are always the double prompt (>>).
*/
printf("%s", buffer+2); /*显 示 该 MATLAB命 令 的 执 行 情 况 */
/*
* Get result of computation.
*/
printf("\nRetrieving X...\n");
if ((result = engGetArray(ep,"X")) == NULL) /*判 断 是 否 可 以 从 MATLAB
引 擎 中 获 得 矩 阵 “ X” */
printf("Oops! You didn't create a variable X.\n\n");
else
printf("X is class %s\t\n", mxGetClassName(result)); /*显 示 矩 阵 “ X”
的 类 型 */
} /* while(result==NULL)*/
/*
* We're done! Free memory, close MATLAB engine and exit.
*/
printf("Done!\n");
mxDestroyArray(result); /*从 内 存 中 撤 销 矩 阵 “ T” */
engClose(ep); /*关 闭 MATLAB引 擎 */
return EXIT_SUCCESS; /*返 回 */
}
4、 引 擎 应 用 程 序 的 编 译
对 于 象 上 例 中 的 控 制 台 程 序 , 可 以 在 MATLAB命 令 行 中 直 接 使 用 带 -f参 数 的 mex命 令 编 译 。
如 果 在 普 通 win32 application中 使 用 MATLAB引 擎 , 情 况 则 比 较 复 杂 。 在 Windows中 , MATLAB引 擎 是 通 过 ActiveX被 调 用 的 。 因 此 你 需 要 先 Create一 个 OLE Automation Sever和 一 个 OLE Client, 然 后 通 过 OLE方 式 调 用 这 个 MATLAB引 擎 。 具 体 做 法 可 参 阅 相 关 MATLAB随 机 文 档 。
5、 总 结
MATLAB引 擎 的 调 用 与 其 它 引 擎 ( 例 如 数 据 库 引 擎 ) 的 调 用 很 类 似 , 其 步 骤 是 联 接 \启 动 引 擎 , 然 后 向 引 擎 发 送 命 令 , 获 得 引 擎 处 理 结 果 。
结 束 语
上 面 简 要 介 绍 了 MATLAB与 C++的 几 种 接 口 方 式 , 我 们 可 以 根 据 要 求 的 不 同 采 用 相 应 的 方 式 。
此 外 , MATLAB还 提 供 了 一 个 数 学 库 , 由 此 数 学 库 , 我 们 可 以 获 得 对 MATLAB内 部 命 令 更 多 的 访 问 权 和 更 灵 活 的 访 问 方 式 。 具 体 内 容 可 参 考 MATLAB的 相 关 随 机 文 档 。
· 参 考 文 献
1、 MATLAB随 机 文 档 : apiguide.pdf
2、 MATLAB随 机 文 档 : apiref.pdf
3、 MATLAB随 机 文 档 : c_math_ref1.pdf
· 致 谢
感 谢 loverboy的 鼓 励 , 他 声 称 要 把 这 些 帖 子 放 到 他 的 主 页 上 , 才 使 得 我 能 够 在 短 时 间 完 成 这 篇 接 口 问 题 的 文 章 , 西 西 。
· 备 注
mex编 译 器 在 VC6下 的 设 置 可 参 阅 本 板 19#文
Bluesky的 意 见 :
VC程 序 员 最 好 用 visual matcom。 VB用 matrixVB mathtool在 主 页 上 提 供 免 费 试 用 , 快 去 下 吧 。 matlab的 功 能 可 在 你 的 VC,VB中 实 现 , 而 且 只 需 两 个 dll即 可 发 行 。
相 关 问 题 :
QA002610 “关于MatLab的站点” <>文章来源Sirius (天狼星) 。
</P> |