Matlab 版 (精华区)
发信人: bage (醍醐灌顶@洗心革面), 信区: Matlab
标 题: Matlab和C++接口中函数注册的实现
发信站: 哈工大紫丁香 (2001年04月13日11:19:11 星期五), 站内信件
Matlab和C++接口中函数注册的实现
李江红 韩正之
摘 要:函数注册在Matlab和C++接口中起着重要的作用。在介绍函数注册作用的基
础上,详细分析了函数注册的过程及应当注意的问题,并给出了一种实现函数注册的最
简单的方法。用实例展示了函数注册的具体实现过程。
关键词:Matlab;C++;函数注册
中图分类号:TP317,TP319 文献标识码:A
文章编号:1001-9081(2000)04-0018-03
FUNCTION REGISTERING IN
THE INTERFACE BETWEEN MATLAB AND C++
LI Jiang-hong HAN Zheng-zhi
(Intelligent Engineer Research Institute of Shanghai Jiaotong University, S
hanghai 200030 China)
Abstract: Function registration plays an important role in the interface
between Matlab and C++. This paper analyzes the procedure of function regis
tering. Each step of function registering is discussed in detail in the pape
r, and at the end,an example is given for illustration.
Key words:Matlab; C++; function registration
1 研究意义
Matlab为用户提供了丰富的Windows图形界面设计方法,使用户能够在利用其强大数
值计算功能的同时设计出友好的图形界面。在编程效率、可读性、可移植性和可扩充性
上,Matlab远远优于其它高级编程语言。Matlab能够设计出功能强大、界面优美、性能
稳定的高质量程序,它受到了越来越多用户的欢迎。然而作为一种以解释方式运行的高
级计算机语言,Matlab程序的执行效率较低。为了解决这一问题,MathWorks公司提供了
Matlab和C的接口。MathWorks公司提供的Matlab和C的接口方式共有三种:(a)将Matlab
程序编译成MEX文件C或C++文件;(b)在C,C++程序中利用Matlab Engine调用Matlab函数
;(c) 在C,C++程序中利用Matlab C Math Library或Matlab C++ Math Library调用Mat
lab函数。其中通过方式(a)、(b)生成的程序只有在安装了Matlab系统上才能正常运行,
而由方式(c) 生成的程序则没有这样的要求,它能够以独立执行程序的形式运行,即使
客户没有安装Matlab系统。方式(c)唯一的缺点就是不能利用Matlab中丰富的图形句柄处
理函数,但是对于VC++等开发工具而言,这不是一个很严重的问题。因此方式(c)是实现
功能和效率兼顾的最好接口方法[2]。
当用方式(c) 生成应用程序时,一个重要的问题就是那些以函数作为自身输入参数
的函数实现问题。众所周知,Matlab提供了一组能完成极值及极值点计算,线性规划,
二次规划以及非线性方程求解等数值运算的优化函数[3]。
在Matlab中使用这组优化函数时,用户定义的待优化函数必须作为输入参数传递给
这些函数。在优化函数运行的过程中,系统将最终执行用户定义的待优化函数,并且这
一切无须程序员的参与。但是当程序员通过方式(c)在C++程序中调用Matlab C++ Math
Library中的优化函数时,事情就变得比较复杂。要利用这些优化函数所提供的数值计算
功能,保证用户定义的待优化函数真正得到执行,程序员就必须自己完成对待优化函数
的注册。因此,函数注册的研究具有重要的实用价值。
2 Matlab和C++接口中函数注册
在C++程序中,当调用优化函数等以函数为输入参数的函数时,Matlab C++ Math L
ibrary调用Matlab C Math Library中的mlfFeval()来执行作为参数传递的函数。在mlf
Feval()中又是通过对转换函数的调用来真正地执行作为参数传递的函数。转换函数和映
射表是这一过程能够顺利进行的重要原因。函数注册就是定义函数的转换函数并建立相
应的它的映射表。对于Matlab C++ Math Library中的函数,MathWorks公司都定义了它
们转换函数并建立了它们的映射表,完成了对它们的注册。但是对于用户自定义的函数
,程序员就必须自己完成这项工作。
函数注册可以分成:(1)定义待注册函数;(2)定义转换函数;(3)建立映射表;(4)
初始化映射表等以下四个部分来完成。下面将对各个部分进行详细地介绍。
(1) 定义待注册函数 待注册函数因用户要求而异。为便于后面的分析,设用户定
义的函数为:
mwArray MyFunc(mwArray x){
……//函数体。
}
注意待注册函数的输入、输出参数的类型必须是mwArray。mwArray是Matlab C++ M
ath Library中最基本的数据类,它对应Matlab中的基本编程单位—数组。
(2) 定义转换函数 转换函数的功能是完成Matlab C Math Library和用户函数之间
的翻译。由于它面向Matlab C Math Library,因此必须用C定义。对(1)中定义的待注册
函数,其转换函数的一般形式如下(为简单起见,该转换函数忽略了错误处理代码):
typedef mwArray (*PMYFUNC) (mwArray);
extern "C" {
int MyThunk (mlfFuncp pFunc, int nArgOut, mxArray **
ArgOut, int nArgIn, mxArray ** ArgIn){
mwArray tmp=mwArray(ArgIn[0],0);
mwArray Out=(*((PMYFUNC)pFunc)) (tmp);
ArgOut[0]=Out.FreezeData( );
return 1
}
}
转换函数共有5个输入参数,以MyThunk为例,pFunc是指向待注册函数的指针;nAr
gIn、nArgOut, 分别是待注册函数的输入、输出参数的个数; ArgIn、ArgOut,则分别是
输入、输出参数构成的数组。其中ArgIn[0]对应第1个输入参数,ArgIn[1]对应第2
个输入参数……。ArgOut的情形类似。
由于转换函数面向Matlab C Math Library,因此它的输入、输出参数中的数组类型
只能是mxArray (mwArray是Matlab C Math Library中基本的数据,它对应Matlab中的基
本编程单位—数组);而注册的函数又只能接受mwArray类型的参数。因此,在调用注册
函数之前必须将mxArray型数据转化为mwArray型数据,如MyThunk中:mwArray tmp=mwA
rray(ArgIn[0],0); 在转换函数返回之前必须将注册的函数的返回值由mwArray型转化
为型mxArray,如MyThunk中:ArgOut[0]=Out.FreezeData()。
(3) 建立映射表 映射表的作用是把待注册函数的名称映射到指向该函数的指针。
映射表中的元素由三元组:函数名称、函数指针、转换函数构成。对(1)、(2)中定义的
待注册函数和转换函数,相应的映射表为:
static mlfFuncTabEnt MfuncTab[]={
{"MyFunc", (mlfFuncp) MyFunc, MyThunk}
{0, 0 ,0}
}
其中mlfFuncTabEnt是Matlab C Math Library中用于存储函数项的数据结构。{0,
0 ,0}表示映射表的结束。
(4) 初始化映射表 初始化映射表的方式比较单一。例如对(3)中的映射表,程序段
:
class feval—init{
feval—init{mlfFevalTableSetup(MfuncTab);}
static feval—init feval—setup;
}
feval—init feval—init::feval—setup;
将完成其初始化。其中mlfFevalTableSetup是Matlab C Math Library中用于初始化
映射表的函数。设置静态对象的目的是保证映射表初始化在系统初始化静态变量时就得
以完成。
从上面的分析可以看出,函数注册的过程比较复杂。不过MathWorks公司注意到了这
个问题,它定义并提供了DECLARE—FEVAL—TABLE, EVAL—ENTRY, END—FEVAL—TABLE等
一组宏来帮助用户简单、轻松地完成函数注册。例如对于(1)中定义的函数MyFunc,程序
段:
DECLARE—FEVAL—TABLE
FEVAL—ENTRY(MyFunc)
END—FEVAL—TABLE
就实现了对MyFunc的注册,它取代了(2)、(3)、(4)中的所有工作。事实上,只要待注册
函数的输入参数数目不大于8,输出参数数目不大于5,就能用这组宏来完成函数注册。
3 应用实例
下面的VC++程序通过调用Matlab C++ Math Library中的fmin(),计算函数
f(x,y)=ex(4x2+2y2+4xy+2y+1)
在y=2时,位于区间[-2,2]中使函数值最小的自变量x的值。
#include "matlab.hpp"
#include <stdlib.h>
/***(1) 定义注册函数 ***/
mwArray MyFunc(mwArray x,mwArray y){
mwArray mResult=exp(x)*(4*x ^ 2+2*y ^ 2+4*x*y+2*y+1);
return mResult;
}
/***(2) 定义转换函数 ***/
typedef mwArray (*PMYFUNC)(mwArray,mwArray);
extern "C"{
int MyThunk(mlfFuncp pFunc, int nArgOut, mxArray **
ArgOut,int nArgIn, mxArray **ArgIn) {
mwArray tmp1=mwArray( ArgIn[0], 0 );
mwArray tmp2=mwArray( ArgIn[1], 0 );
mwArray Out=(*((PMYFUNC)pFunc))(tmp1,tmp2);
ArgOut[0]=Out.FreezeData();
return 1;
}
}
/***(3) 建立映射表 ***/
static mlfFuncTabEnt MFuncTab[] ={
{ "MyFunc", (mlfFuncp)MyFunc, MyThunk },
{ 0, 0, 0 }
};
/***(4) 初始化映射表 ***/
class feval—init {
feval—init() { mlfFevalTableSetup( MFuncTab ); }
static feval—init feval—setup;
};
feval—init feval—init::feval—setup;
/***可以取代(2)(3)(4)的宏注册函数 ****/
/*** DECLARE—FEVAL—TABLE ***/
/*** FEVAL—ENTRY(MyFunc) ***/
/*** END—FEVAL—TABLE ***/
/***** 主程序 *****/
void main(void){
mwArray mStart,mEnd,mP,mOption;
mStart=-2,mEnd=2;mP=2.0;
mwArray mResult=fmin("MyFunc",mStart,mEnd,mOption,mP);
cout < < mResult< < endl;
}
作者简介:李江红(1970-)男,湖南长沙人,博士研究生,主要研究方向:随机决策以及
智能控制;韩正之(1947-)男,上海人,教授,主要研究方向:非线性控制以及智能控
制。
作者单位:李江红(上海交通大学智能工程研究所 上海 200030)
韩正之(上海交通大学智能工程研究所 上海 200030)
参考文献
[1] 薛定宇. 控制系统计算机辅助设计—MATLAB语言及应用[M].北京:清华大学出
版社, 1996.17-19.
[2] MATLAB C++ math Libarary User′s Guide[Z]. The Math Works, Inc., 19
98.2-18.
[3] 施阳,李俊.MATLAB语言工具箱—TOOLBOX实用指南[M].西安:西北工业大学出版
社,1998.100-101
--
ooooO Ooooo *********************************
( ) ( ) # 大肚能容,容天下难容之事 #
\ ( ) / # 开口便笑,笑世间可笑之人 #
\ ) ( / *********************************
~~ ~~
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: bage.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.524毫秒