?? 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> 韓正之(上海交通大學智能工程研究所 上?!?00030)</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 + -