📄 matlab和c++接口中函数注册的实现.htm
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0050)http://passmatlab.myetang.com/matlab/file/p_25.htm -->
<!-- saved from url=(0078)http://periodical.wanfangdata.com.cn/periodical/jsjyy/jsjy2000/0004/000407.htm --><HTML><HEAD><TITLE>Matlab和C++接口中函数注册的实现</TITLE>
<META content="text/html; charset=gb2312" http-equiv=Content-Type>
<META content="MSHTML 5.00.3315.2870" name=GENERATOR></HEAD>
<BODY bgColor=#ffffff link=#000000>
<DIV align=left>
<TABLE border=0 cellPadding=0 cellSpacing=0>
<TBODY>
<TR><FONT face=宋体 lang=ZH-CN size=3>
<TD width=219>
<P align=center> </P></TD></FONT>
<TD width=320>
<P align=center> </P></TD>
<TD align=right width=145>
<P align=center> </P></TD></TR>
<TR><FONT face=宋体 lang=ZH-CN size=3>
<TD colSpan=3 width=684>
<HR>
</TD></FONT></TR></TBODY></TABLE></DIV>
<TABLE border=0 width="90%">
<TBODY>
<TR>
<TD>
<P align=center><FONT size=3></FONT><SPAN class=tm><FONT face=宋体
size=5><STRONG>Matlab和C++接口中函数注册的实现</STRONG></FONT></SPAN></P>
<P align=center><FONT size=3></FONT><FONT face=宋体
size=3>李江红 韩正之</FONT></P>
<P align=left><FONT size=3><FONT
face=宋体> <STRONG>摘 要:</STRONG></FONT></FONT><FONT face=宋体 size=3><SPAN
class=zy>函数注册在Matlab和C++接口中起着重要的作用。在介绍函数注册作用的基础上,详细分析了函数注册的过程及应当注意的问题,并给出了一种实现函数注册的最简单的方法。用实例展示了函数注册的具体实现过程。</SPAN><BR> <STRONG>关键词:</STRONG><SPAN
class=gj>Matlab;C++;函数注册</SPAN><BR> <STRONG>中图分类号:</STRONG><SPAN
class=fl>TP317,TP319</SPAN> <STRONG>文献标识码:</STRONG><SPAN
class=wm>A</SPAN><BR> <STRONG>文章编号</STRONG>:<SPAN
class=wh>1001-9081(2000)04-0018-03</SPAN></FONT></P>
<P align=center><FONT size=3></FONT><STRONG><FONT face="Times New Roman"
size=4><SPAN class=tme>FUNCTION REGISTERING IN <BR>THE INTERFACE BETWEEN
MATLAB AND C++</SPAN></FONT></STRONG></P>
<P align=center><FONT face="Times New Roman">LI Jiang-hong</FONT> <FONT
face="Times New Roman">HAN Zheng-zhi<BR></FONT>(<FONT
face="Times New Roman">Intelligent Engineer Research Institute of Shanghai
Jiaotong University, Shanghai 200030 China</FONT>)</P>
<P align=left> <FONT face="Times New Roman"><STRONG>Abstract:
</STRONG><SPAN class=zye>Function registration plays an important role in
the interface between Matlab and C++. This paper analyzes the procedure of
function registering. Each step of function registering is discussed in
detail in the paper, and at the end</SPAN></FONT><SPAN class=zye>,<FONT
face="Times New Roman">an example is given for
illustration.</FONT></SPAN><FONT face="Times New Roman"
size=3><BR></FONT><FONT size=3> </FONT><FONT face="Times New Roman"
size=3><STRONG>Key words:</STRONG><SPAN class=gje>Matlab; C++; function
registration</SPAN></FONT></P>
<P align=left><FONT size=3></FONT><FONT face=宋体
size=4><STRONG>1 研究意义</STRONG></FONT></P><FONT size=3>
<P><FONT
face=宋体> 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调用Matlab函数。其中通过方式(a)、(b)生成的程序只有在安装了Matlab系统上才能正常运行,而由方式(c)
生成的程序则没有这样的要求,它能够以独立执行程序的形式运行,即使客户没有安装Matlab系统。方式(c)唯一的缺点就是不能利用Matlab中丰富的图形句柄处理函数,但是对于VC++等开发工具而言,这不是一个很严重的问题。因此方式(c)是实现功能和效率兼顾的最好接口方法<SUP>[2]</SUP>。<BR> 当用方式(c)
生成应用程序时,一个重要的问题就是那些以函数作为自身输入参数的函数实现问题。众所周知,Matlab提供了一组能完成极值及极值点计算,线性规划,二次规划以及非线性方程求解等数值运算的优化函数<SUP>[3]</SUP>。<BR> 在Matlab中使用这组优化函数时,用户定义的待优化函数必须作为输入参数传递给这些函数。在优化函数运行的过程中,系统将最终执行用户定义的待优化函数,并且这一切无须程序员的参与。但是当程序员通过方式(c)在C++程序中调用Matlab
C++ Math
Library中的优化函数时,事情就变得比较复杂。要利用这些优化函数所提供的数值计算功能,保证用户定义的待优化函数真正得到执行,程序员就必须自己完成对待优化函数的注册。因此,函数注册的研究具有重要的实用价值。</FONT></P></FONT>
<P align=left><FONT size=3></FONT><FONT face=宋体
size=4><STRONG>2 Matlab和C++接口中函数注册</STRONG></FONT></P><FONT size=3>
<P><FONT face=宋体> 在C++程序中,当调用优化函数等以函数为输入参数的函数时,Matlab C++ Math
Library调用Matlab C Math
Library中的mlfFeval()来执行作为参数传递的函数。在mlfFeval()中又是通过对转换函数的调用来真正地执行作为参数传递的函数。转换函数和映射表是这一过程能够顺利进行的重要原因。函数注册就是定义函数的转换函数并建立相应的它的映射表。对于Matlab
C++ Math
Library中的函数,MathWorks公司都定义了它们转换函数并建立了它们的映射表,完成了对它们的注册。但是对于用户自定义的函数,程序员就必须自己完成这项工作。<BR> 函数注册可以分成:(1)定义待注册函数;(2)定义转换函数;(3)建立映射表;(4)初始化映射表等以下四个部分来完成。下面将对各个部分进行详细地介绍。<BR> (1)
定义待注册函数 待注册函数因用户要求而异。为便于后面的分析,设用户定义的函数为:<BR> mwArray MyFunc(mwArray
x){<BR> ……//函数体。<BR> }<BR> 注意待注册函数的输入、输出参数的类型必须是mwArray。mwArray是Matlab
C++ Math Library中最基本的数据类,它对应Matlab中的基本编程单位—数组。<BR> (2)
定义转换函数 转换函数的功能是完成Matlab C Math Library和用户函数之间的翻译。由于它面向Matlab C Math
Library,因此必须用C定义。对(1)中定义的待注册函数,其转换函数的一般形式如下(为简单起见,该转换函数忽略了错误处理代码):<BR> typedef
mwArray (*PMYFUNC) (mwArray);<BR> extern "C" {<BR> int MyThunk (mlfFuncp
pFunc, int nArgOut, mxArray **<BR> ArgOut, int nArgIn, mxArray **
ArgIn){<BR> mwArray tmp=mwArray(ArgIn[0],0);<BR> mwArray
Out=(*((PMYFUNC)pFunc)) (tmp);<BR> ArgOut[0]=Out.FreezeData(
);<BR> return
1<BR> }<BR> }<BR> 转换函数共有5个输入参数,以MyThunk为例,pFunc是指向待注册函数的指针;nArgIn、nArgOut,
分别是待注册函数的输入、输出参数的个数;
ArgIn、ArgOut,则分别是输入、输出参数构成的数组。其中ArgIn[0]对应第1个输入参数,ArgIn[1]对应第2个输入参数……。ArgOut的情形类似。<BR> 由于转换函数面向Matlab
C Math Library,因此它的输入、输出参数中的数组类型只能是mxArray (mwArray是Matlab C Math
Library中基本的数据,它对应Matlab中的基本编程单位—数组);而注册的函数又只能接受mwArray类型的参数。因此,在调用注册函数之前必须将mxArray型数据转化为mwArray型数据,如MyThunk中:mwArray
tmp=mwArray(ArgIn[0],0);
在转换函数返回之前必须将注册的函数的返回值由mwArray型转化为型mxArray,如MyThunk中:ArgOut[0]=Out.FreezeData()。<BR> (3)
建立映射表 映射表的作用是把待注册函数的名称映射到指向该函数的指针。映射表中的元素由三元组:函数名称、函数指针、转换函数构成。对(1)、(2)中定义的待注册函数和转换函数,相应的映射表为:<BR> static
mlfFuncTabEnt MfuncTab[]={<BR> {"MyFunc", (mlfFuncp) MyFunc,
MyThunk}<BR> {0, 0 ,0}<BR> }<BR> 其中mlfFuncTabEnt是Matlab C Math
Library中用于存储函数项的数据结构。{0, 0 ,0}表示映射表的结束。<BR> (4)
初始化映射表 初始化映射表的方式比较单一。例如对(3)中的映射表,程序段:<BR> class
feval<SUB>—</SUB>init{<BR> feval<SUB>—</SUB>init{mlfFevalTableSetup(MfuncTab);}<BR> static
feval<SUB>—</SUB>init
feval<SUB>—</SUB>setup;<BR> }<BR> feval<SUB>—</SUB>init
feval<SUB>—</SUB>init::feval<SUB>—</SUB>setup;<BR> 将完成其初始化。其中mlfFevalTableSetup是Matlab
C Math
Library中用于初始化映射表的函数。设置静态对象的目的是保证映射表初始化在系统初始化静态变量时就得以完成。<BR> 从上面的分析可以看出,函数注册的过程比较复杂。不过MathWorks公司注意到了这个问题,它定义并提供了DECLARE<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE,
EVAL<SUB>—</SUB>ENTRY,
END<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE等一组宏来帮助用户简单、轻松地完成函数注册。例如对于(1)中定义的函数MyFunc,程序段:<BR> DECLARE<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE<BR> FEVAL<SUB>—</SUB>ENTRY(MyFunc)<BR> END<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE<BR>就实现了对MyFunc的注册,它取代了(2)、(3)、(4)中的所有工作。事实上,只要待注册函数的输入参数数目不大于8,输出参数数目不大于5,就能用这组宏来完成函数注册。</FONT></P></FONT>
<P align=left><FONT size=3></FONT><FONT face=宋体
size=4><STRONG>3 应用实例</STRONG></FONT></P><FONT size=3>
<P><FONT face=宋体> 下面的VC++程序通过调用Matlab C++ Math
Library中的fmin(),计算函数<BR> f(x,y)=e<SUP>x</SUP>(4x<SUP>2</SUP>+2y<SUP>2</SUP>+4xy+2y+1)<BR> 在y=2时,位于区间[-2,2]中使函数值最小的自变量x的值。<BR>#include
"matlab.hpp"<BR>#include <stdlib.h><BR>/***(1) 定义注册函数
***/<BR>mwArray MyFunc(mwArray x,mwArray y){<BR> mwArray
mResult=exp(x)*(4*x ^ 2+2*y ^ 2+4*x*y+2*y+1);<BR> return
mResult;<BR>}<BR>/***(2) 定义转换函数 ***/<BR>typedef mwArray
(*PMYFUNC)(mwArray,mwArray);<BR>extern "C"{<BR> int MyThunk(mlfFuncp
pFunc, int nArgOut, mxArray **<BR> ArgOut,int nArgIn, mxArray
**ArgIn) {<BR> mwArray tmp1=mwArray( ArgIn[0], 0 );<BR> mwArray
tmp2=mwArray( ArgIn[1], 0 );<BR> mwArray
Out=(*((PMYFUNC)pFunc))(tmp1,tmp2);<BR> ArgOut[0]=Out.FreezeData();<BR> return
1;<BR> }<BR>}<BR>/***(3) 建立映射表 ***/<BR>static mlfFuncTabEnt MFuncTab[]
={<BR>{ "MyFunc", (mlfFuncp)MyFunc, MyThunk },<BR>{ 0, 0, 0
}<BR>};<BR>/***(4) 初始化映射表 ***/<BR>class feval<SUB>—</SUB>init
{<BR> feval<SUB>—</SUB>init() { mlfFevalTableSetup( MFuncTab );
}<BR> static feval<SUB>—</SUB>init
feval<SUB>—</SUB>setup;<BR> };<BR>feval<SUB>—</SUB>init
feval<SUB>—</SUB>init::feval<SUB>—</SUB>setup;<BR>/***可以取代(2)(3)(4)的宏注册函数 ****/<BR>/*** DECLARE<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE ***/<BR>/*** FEVAL<SUB>—</SUB>ENTRY(MyFunc) ***/<BR>/*** END<SUB>—</SUB>FEVAL<SUB>—</SUB>TABLE ***/<BR>/***** 主程序 *****/<BR>void
main(void){<BR> mwArray
mStart,mEnd,mP,mOption;<BR> mStart=-2,mEnd=2;mP=2.0;<BR> mwArray
mResult=fmin("MyFunc",mStart,mEnd,mOption,mP);<BR> cout < <
mResult< < endl;<BR> }</FONT></P></FONT>
<P align=left><FONT size=3><FONT face=宋体>作者简介:</FONT></FONT><FONT face=宋体
size=3><SPAN
class=zj><STRONG>李江红</STRONG>(1970-)男,湖南长沙人,博士研究生,主要研究方向:随机决策以及智能控制</SPAN>;<STRONG>韩正之</STRONG>(1947-)男,上海人,教授,主要研究方向:非线性控制以及智能控制。<BR>作者单位:</FONT><SPAN
class=zz>李江红(上海交通大学智能工程研究所 上海 200030)<BR> 韩正之(上海交通大学智能工程研究所 上海 200030)</SPAN></P><FONT
size=3>
<P align=center><FONT face=宋体><STRONG>参考文献</STRONG></FONT></P></FONT>
<P align=left><FONT size=3></FONT><FONT face=宋体 size=3><SPAN
class=wx>[1] 薛定宇. 控制系统计算机辅助设计—MATLAB语言及应用[M].北京:清华大学出版社,
1996.17-19.<BR>[2] MATLAB C++ math Libarary User′s Guide[Z]. The Math
Works, Inc.,
1998.2-18.<BR>[3] 施阳,李俊.MATLAB语言工具箱—TOOLBOX实用指南[M].西安:西北工业大学出版社,1998.100-101.</SPAN></FONT></P>
<P align=left><FONT face=宋体 size=3><A
href="http://passmatlab.myetang.com/matlab/prec.htm">back</A></FONT></P></TD></TR></TBODY></TABLE></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -