原文地址:http://blog.chinaunix.net/uid-20776117-id-1847019.html
在C、C++中调用Matlab
Matlab是美国MathWorks公司的产品,是一种以矩阵为基本编程单位的高效数值计算语言。Matlab集科学计算、图像处理、声音处理于一体,为用户提供了丰富的Windows图形界面设计方法,使用户能够在利用其强大数值计算功能的同时设计出友好的图形界面
。Matlab已经被证明是在应用数学、物理、工程学和其它涉及复杂数值计算等应用领域中解决问题的优秀工具。Matlab能够在Win95/98、Win2000、Linux和Unix等多种操作系统平台上运行。
C、C++是众多程序员十分喜爱的高级程序设计语言,但其在数值处理分析和算法工具等方面,效率远远低于Matlab 语言;在准确方便地绘制数据图形方面,Matlab 语言具有C和C++无法比拟的优势。但Matlab作为一种以解释方式运行的计算机语言,其程序的执行效率较低,而且不能实现端口操作和实时控制。因此,若能将两者结合运用,实现优势互补,将获得极大的效益。为此,MathWorks公司提供了Matlab和C、C++的接口。通过接口,用户既可在C程序中调用Matlab的函数,也可在Matlab中调用C或C++程序,从而实现Matlab和C、C++的混合编程。本文主要讨论如何在C、C++中调用Matlab。
一、过程分析
在C、C++中调用Matlab的主要过程如下所示:
1) 首先调用engOpen函数打开一个Matlab工程。
2) 生成mxArray。
在Matlab中,所有变量类型,如标量、向量、矩阵、字符串、细胞矩阵和结构,都以mxArrays形式来保存,固数据操作都必须通过这些mxArrays来完成。生成mxArray有两种不同的方式。一是用mxCreate函数来创建矩阵,之后用mxSetName函数对它进行命名。
另一种方式是选择将一个自定义的数据结构复制到mxArray中,值得注意的是Matlab在存储矩阵时是按列序保存的,而在C、C++中是按行序保存的,所以转换时注意分清下标。
3) 调用engPutArray函数将矩阵放入到Matlab工作区中。
4) 通过engEvalString函数向Matlab传递命令,如果成功,函数返回值为此0,否则返回一个非0值。
5) 将Matlab中的运行结果回传给C、C++
二、程序实现
我们通过一个简单的程序demo.c来说明C、C++对Matlab的调用。
#include
#include
#include
#include
/*在头文件中加入engine.h。其包含了调用的Matlab函数声明。*/
#include "engine.h"
int PASCAL WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
Engine *ep; // 定义Matlab 引擎
mxArray *a_ptr=NULL;
char buffer[300]; // 定义数据缓冲区
double *wu;
int i,j;
/*创建一个新矩阵*/
a_ptr=mxCreateDoubleMatrix(10,10,mxREAL);
mxSetName(a_ptr,"wu");
wu=mxGetPr(a_ptr);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
wu[i+10*j]=(j+1)*(j+1)*(i+1)*(i+1);
}
}
/* 打开Matlab 引擎*/
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start Matlab engine",
(LPSTR) "demo.c", MB_OK);
exit(-1);
}
/*传递新矩阵*/
engPutArray(ep, a_ptr);
/*画出图形并保存*/
engEvalString(ep,"mesh(wu);");
engEvalString(ep,"print picture.eps -deps;");
/* 获取Matlab 输出 */
engOutputBuffer(ep, buffer, 300);
/*关闭Matlab 引擎,结束调用*/
engClose(ep);
mxDestroyArray(a_ptr);
return(0);
}
当然,该程序在编译之前还需设置一些环境参数。在不同的开发环境中,其设置方法略有差异,我们以Borland C++ builder开发平台为例加以说明。
1) 首先必须完成Matlab中链接库的导入工作。在Matlab\extern\include中存在_libmx.def、_libmat.def、_libeng.def等定义文件,在DOS环境中对它们执行命令:
c:\matlab\extern\include>implib 文件名.lib 文件名.def 将获得_libmx.lib、_libmat.lib、_libeng.lib等新文件。再将这3个新文件拷贝到 目录matlab\extern\
lib中即可。
2)在BCB中新建一工程,在其中加入文件demo.c
3)打开Project|Option... 对话框,点击Directories/Conditionals。在Include Path 中,加入目录路径\extern\include,该路径包含了engine.h 和matlab .h 等有用的头文件。在Library Path 中,加入\bin和\extern\lib 。这两个目录路径包含了外部调用的LIB文件。
4)点选Project|Add to Project... 对话框,加入如下库文件:
_libeng.lib,_libmat.lib 和_libmx.lib。
完成以上配置后,即可编译运行。程序执行结果如下图所示。
最后,需要说明的是,使用这种方法调用Matlab 不能脱离Matlab 环境的支撑。另一种方法则是完全脱离Matlab环境,通过动态连接库方式实现对Matlab工具箱函数的调用,这可以通过Mathtools公司的开发平台Mediva来实现。Mediva软件功能相当强大,提供近千个Matlab的基本功能函数,通过一些必要的设置,就可以直接实现与C、C++的混合编程,而不必再依赖Matlab。限于篇幅,在此不作详细介绍,感兴趣的用户可以通过访问网站www.mathtools.com免费下载试用。
Matlab是美国MathWorks公司的产品,是一种以矩阵为基本编程单位的高效数值计算语言。Matlab集科学计算、图像处理、声音处理于一体,为用户提供了丰富的Windows图形界面设计方法,使用户能够在利用其强大数值计算功能的同时设计出友好的图形界面
。Matlab已经被证明是在应用数学、物理、工程学和其它涉及复杂数值计算等应用领域中解决问题的优秀工具。Matlab能够在Win95/98、Win2000、Linux和Unix等多种操作系统平台上运行。
C、C++是众多程序员十分喜爱的高级程序设计语言,但其在数值处理分析和算法工具等方面,效率远远低于Matlab 语言;在准确方便地绘制数据图形方面,Matlab 语言具有C和C++无法比拟的优势。但Matlab作为一种以解释方式运行的计算机语言,其程序的执行效率较低,而且不能实现端口操作和实时控制。因此,若能将两者结合运用,实现优势互补,将获得极大的效益。为此,MathWorks公司提供了Matlab和C、C++的接口。通过接口,用户既可在C程序中调用Matlab的函数,也可在Matlab中调用C或C++程序,从而实现Matlab和C、C++的混合编程。本文主要讨论如何在C、C++中调用Matlab。
一、过程分析
在C、C++中调用Matlab的主要过程如下所示:
1) 首先调用engOpen函数打开一个Matlab工程。
2) 生成mxArray。
在Matlab中,所有变量类型,如标量、向量、矩阵、字符串、细胞矩阵和结构,都以mxArrays形式来保存,固数据操作都必须通过这些mxArrays来完成。生成mxArray有两种不同的方式。一是用mxCreate函数来创建矩阵,之后用mxSetName函数对它进行命名。
另一种方式是选择将一个自定义的数据结构复制到mxArray中,值得注意的是Matlab在存储矩阵时是按列序保存的,而在C、C++中是按行序保存的,所以转换时注意分清下标。
3) 调用engPutArray函数将矩阵放入到Matlab工作区中。
4) 通过engEvalString函数向Matlab传递命令,如果成功,函数返回值为此0,否则返回一个非0值。
5) 将Matlab中的运行结果回传给C、C++
二、程序实现
我们通过一个简单的程序demo.c来说明C、C++对Matlab的调用。
#include
#include
#include
#include
/*在头文件中加入engine.h。其包含了调用的Matlab函数声明。*/
#include "engine.h"
int PASCAL WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
Engine *ep; // 定义Matlab 引擎
mxArray *a_ptr=NULL;
char buffer[300]; // 定义数据缓冲区
double *wu;
int i,j;
/*创建一个新矩阵*/
a_ptr=mxCreateDoubleMatrix(10,10,mxREAL);
mxSetName(a_ptr,"wu");
wu=mxGetPr(a_ptr);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
wu[i+10*j]=(j+1)*(j+1)*(i+1)*(i+1);
}
}
/* 打开Matlab 引擎*/
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start Matlab engine",
(LPSTR) "demo.c", MB_OK);
exit(-1);
}
/*传递新矩阵*/
engPutArray(ep, a_ptr);
/*画出图形并保存*/
engEvalString(ep,"mesh(wu);");
engEvalString(ep,"print picture.eps -deps;");
/* 获取Matlab 输出 */
engOutputBuffer(ep, buffer, 300);
/*关闭Matlab 引擎,结束调用*/
engClose(ep);
mxDestroyArray(a_ptr);
return(0);
}
当然,该程序在编译之前还需设置一些环境参数。在不同的开发环境中,其设置方法略有差异,我们以Borland C++ builder开发平台为例加以说明。
1) 首先必须完成Matlab中链接库的导入工作。在Matlab\extern\include中存在_libmx.def、_libmat.def、_libeng.def等定义文件,在DOS环境中对它们执行命令:
c:\matlab\extern\include>implib 文件名.lib 文件名.def 将获得_libmx.lib、_libmat.lib、_libeng.lib等新文件。再将这3个新文件拷贝到 目录matlab\extern\
lib中即可。
2)在BCB中新建一工程,在其中加入文件demo.c
3)打开Project|Option... 对话框,点击Directories/Conditionals。在Include Path 中,加入目录路径\extern\include,该路径包含了engine.h 和matlab .h 等有用的头文件。在Library Path 中,加入\bin和\extern\lib 。这两个目录路径包含了外部调用的LIB文件。
4)点选Project|Add to Project... 对话框,加入如下库文件:
_libeng.lib,_libmat.lib 和_libmx.lib。
完成以上配置后,即可编译运行。程序执行结果如下图所示。
最后,需要说明的是,使用这种方法调用Matlab 不能脱离Matlab 环境的支撑。另一种方法则是完全脱离Matlab环境,通过动态连接库方式实现对Matlab工具箱函数的调用,这可以通过Mathtools公司的开发平台Mediva来实现。Mediva软件功能相当强大,提供近千个Matlab的基本功能函数,通过一些必要的设置,就可以直接实现与C、C++的混合编程,而不必再依赖Matlab。限于篇幅,在此不作详细介绍,感兴趣的用户可以通过访问网站www.mathtools.com免费下载试用。