版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、在matlab環(huán)境下訪問外部函數的共享庫文件在matlab環(huán)境下訪問外部函數的共享庫文件 編輯整理:尊敬的讀者朋友們:這里是精品文檔編輯中心,本文檔內容是由我和我的同事精心編輯整理后發(fā)布的,發(fā)布之前我們對文中內容進行仔細校對,但是難免會有疏漏的地方,但是任然希望(在matlab環(huán)境下訪問外部函數的共享庫文件)的內容能夠給您的工作和學習帶來便利。同時也真誠的希望收到您的建議和反饋,這將是我們進步的源泉,前進的動力。本文可編輯可修改,如果覺得對您有幫助請收藏以便隨時查閱,最后祝您生活愉快 業(yè)績進步,以下為在matlab環(huán)境下訪問外部函數的共享庫文件的全部內容。在matlab環(huán)境下訪問外部函數的共享
2、庫文件,必須首先把該庫文件加載到內存中。一旦加載成功,就能直接在matlab中直接請求關于函數的任何信息。而當不再需要該庫時,就應當及時把庫文件從內存中卸載以節(jié)省內存開銷。加載庫語法:loadlibrary(shrlib,hfile)其中shrlib為加載的動態(tài)鏈接庫文件名(filename。dll),hfile為頭文件名,它包含函數原型。例如,當加載包含matlab中mx程序的libmx庫時,可以使用下列語句.hfile=matlabrootexternincludematrix。h;loadlibray(libmx, hfile)卸載庫語法:unloadlibrary libmx使用兩個函
3、數可以獲取加載庫的信息:libfunctions(libname) or libfunctions libnamelibfunctionsview(libname) or libfunctionsview libname這兩個函數的不同之處在于顯示結果的方式不同,后者是以圖形的方式顯示在新的窗口中.而前者返回庫libmx中有哪些可用的函數。請看示例:libfunctions libmxmethods for class lib。libmx:mxaddfield mxgetfieldnumber mxislogicalscalartruemxarraytostring mxgetimagdata
4、 mxisnanmxcalcsinglesubscript mxgetinf mxisnumericmxcalloc mxgetir mxisobjectmxclearscalardoubleflag mxgetjc mxisopaquemxcreatecellarray mxgetlogicals mxisscalardoubleflagset如果加上命令開頭full,則可以顯示函數返回值的細節(jié)。libfunctions libmx -fullmethods for class lib。libmx:mxclassid, matlab array mxgetclassid(matlab arr
5、ay)lib。pointer, matlab array mxgetdata(matlab array)matlab array, voidptr mxsetdata(matlab array, voidptr)lib。pointer, matlab array mxgetpr(matlab array)matlab array, doubleptr mxsetpr(matlab array, doubleptr)uint8 mxisfinite(double)uint8 mxisinf(double)值得注意的是,這兩個函數返回值的類型均是matlab的數據類型,雖然函數是利用c語言編寫的。
6、調用庫函數一旦庫函數被加載到了內存空間,只要指定庫名、函數名和變量就可以使用calllib函數調用庫中的任何函數了。語法格式:calllib(libname,funcname,arg1,argn)下列語句顯示如何操作:hfile=c:matlab7externincludematrix.h;loadlibrary(libmx,hfile);y=rand(4,7,2); %produce a 3d array, there are 56 elements in itcalllib(libmx,mxgetnumberofelements,y)ans=56calllib(libmx,mxgetcla
7、ssid,y)ans=mxdouble_class傳遞變量當調用外部庫里的函數時,該為函數提供哪種類型的變量呢?matlab的externexamplesshrlibshrlibsample庫里對每一種特殊的變量類型都作出了說明。但我們首先必須把該庫文件的路徑添加到matlab的搜索路徑中來,或者使該庫文件所在的目錄成為當前目錄,兩種做法的命令如下。addpath(c:matlab7externexamplesshrlib)cd(c:matlab7externexamplesshrlib)下面的例子就是加載該庫并顯示了其中的一些函數。loadlibrary shrlibsample shrli
8、bsample.hlibfunctions shrlibsample full執(zhí)行上述兩行后,返回:functions in library shrlibsample:double, doubleptr adddoubleref(double, doubleptr, double)double addmixedtypes(int16, int32, double)double, c_structptr addstructbyref(c_structptr)double addstructfields(c_struct)c_structptrptr allocatestruct(c_struct
9、ptrptr)voidptr deallocatestruct(voidptr)doubleptr multdoublearray(doubleptr, int32)lib.pointer, doubleptr multdoubleref(doubleptr)int16ptr multiplyshort(int16ptr, int32)string readenum(enum1)string, string stringtoupper(string)這里所有的函數都是用c語言編寫的.一些通用的規(guī)則在函數的輸入輸出變量問題上,以下幾點應注意:1。許多變量類型,象int32、double與c語言的
10、數據類型非常相象.這些變量只需要傳遞matlab型的數據就可以了.2。而有些c語言的變量類型,象*double、還有預定義型與標準matlab數據類型是完全不同的。這種情況下,有兩種選擇,要么給外部函數的入參傳遞標準的matlab數據類型,讓matlab程序自動轉化,要么先使用matlab提供的轉化函數,如libstruct、libpointer自己轉化。關于轉化,可以參考data conversion.3.c語言通??梢园葱螀鬟f變量,但matlab不支持這種做法,不過可以創(chuàng)造matlabptr或ptrptr型的變量,去兼容c語言的形參。4。c語言通常還可以通過形參來返回輸入變量的值,而ma
11、tlab需要額外的變量來獲得返回值。傳遞變量的通用規(guī)則1。庫函數傳遞形參時,標量不必非得聲明.2。如果庫函數使用單下標來引用二維矩陣元素時,請記住,c語言是逐行處理矩陣元素,而matlab是按列優(yōu)先處理的。因此迎合c語言的習慣,可以在給matlab函數傳遞變量之前把矩陣進行轉置,從函數返回后再轉置回來就行了.3.由上可知,當傳遞的矩陣超過二維時,matlab會改變矩陣的行列結構,為了確保矩陣的結構不被破壞,可以事先記錄矩陣的結構,在調用結束后利用reshape函數還原即可.例如:vs=size(vin); suppose the dimention of vector vin is 2-by-
12、5by2vout=calllib(shrlibsample,multdoublearray,vin,20); %dimention have been altered ans= 2 10vout=reshape(vout,vs); %restore the array to 2-by-5by-2size(vout)ans= 2 5 24.當支持可選參數時,可用一空矩陣來傳遞一個null型參數。這是在變量為ptr或ptrptr型時唯一的選擇。傳參外部庫的許多函數是傳遞形參的,為了能與這些函數交互,matlab通常傳遞一個叫“指針對象的變量,不過別把它與傳參混同了。數據轉化在多數情況下,傳遞給外部
13、庫函數或從外部庫函數返回的數據類型自動被matlab轉化,然而,或許你偶爾也希望有些時侯能手動轉化:1。當需要傳遞相同的數據給一系列庫函數時,可能手動轉化要比讓matlab自動轉化更為明智,更能節(jié)省時間.2。當傳遞大結構的數據時,手動轉化數據使之匹配c結構而不是直接采用通用的matlab型數據的做法,比直接使用libstruct函數把c結構型的數據轉換成matlab型數據更能節(jié)省內存.3。當外部函數使用超過一層引用(例如,指向指針的指針變量double *)時,用libpointer函數構造一個參數,比直接讓matlab自動轉化數據要好。原始類型共享庫接口支持所有標準c數據類型。下表顯示了c與
14、matlab等價的數據類型。c類型(32位機器)等價matlab類型char, byteint8unsigned char, byteuint8shortint16unsigned shortuint16int, longint32unsigned int, unsigned longuint32floatsingledoubledoublechar string(1by-n char array)下表顯示的lib。pointer類中的數據類型,非matlab標準類型c數據類型(32位機器)擴展matlab數據類型integer pointer types (int *)(u) int (si
15、ze) ptrfloat singleptrdouble doubleptrmxarray *matlab arrayvoid voidptrtype same as typeptr with an added ptr(e.g。,double * is doubleptrptr)matlab可以自動把轉化數據為外部庫函數所需要的任何原型數據,這就意味著可以傳遞一個雙精度型數據給一個8位整數型變量。下述c函數接受短整型、整型和雙精度型數據:double addmixedtypes(short x, int y, double z) return (x+y+z);你可以極其簡單地在matlab中只
16、傳遞給該函數以雙精度變量,matlab自動判斷每個變量接受何種類型的變量,并作近似轉化.calllib (shrlibsample,addmixedtypes, 127, 33000, pi)ans= 3.3130e+004轉化參數當外部函數原型定義一個形參時,matlab能自動地把一個按值傳遞的變量轉化為形參.因此,當給一個雙精度指針變量賦一雙精度變量時,matlab會自動地把該雙精度變量轉化為雙精度形參。adddoubleref是一個接受雙精度指針型形參的函數:double adddoubleref( double x, bouble *y, double z) return (x+ *y
17、 +z);用三個雙精度變量調用該函數,matlab自動處理數據轉化:calllib (shrlibsample, adddoubleref, 1.78, 5.42, 13.3)ans= 20.5000字符串當變量需要字符型指針數據時,你可以傳遞一個matlab型字符串(矩陣)。下述c函數接受一個字符指針型數據:char * stringtoupper (char input) char *p=input; if (p!=null) while (*p!=0) p+=toupper(*p); return input;libfunctions顯示,你可以用一個matlab字符串作為輸入。libf
18、unctions shrlibsample full string, string stringtoupper (string )定義一個matlab字符矩陣str,把它傳遞給變量。str=this was a mixed case string; %matlab中字符串以“”號對表示calllib( shrlibsample, stringtoupper, str)ans= this was a mixed string注意:雖然matlab傳遞給變量的很象字符型的形參,但它并不真正的參數類型.因為它并不包括matlab字符矩陣str的地址。因此當函數執(zhí)行完畢時,字符串的值并未改變。枚舉型如
19、果變量被定義為c中的枚舉型,你可以傳遞枚舉型或一個與枚舉值等價的整數.shrlibsample庫中的readenum函數返回與傳入變量相應的枚舉型。下述為enum1的定義和c語言函數readenum:enum enum1 en1=1,en2, en4=4 tenum1;char *readenum(tenum1 val) switch (val) case 1:return “you chose en1”; case 2:return “you chose en2; case 4:return “you chose en4”; default: return “enum not defined
20、”; matlab,你可以用一個枚舉型字符或等價的整數來表示枚舉型數據。上述中定義的枚舉型數據tenum1中,en4與4等價:calllib (shrlibsample, readenum, en4)ans= you chose en4calllib (shrlibsampel, readenum, 4)ans= you chose en4結構體型當庫函數接受結構體型變量時,你需要給它傳遞與在結構體定義時擁有相同域名的結構體變量。為了確定結構體變量的域和類型,你可以:1.查詢庫文檔2.在加載到matlab的庫的頭文件中尋找結構體的定義。你也可以在matlab中采用下述步驟來確定外部函數定義過的
21、結構體的域名.1。利用libfunctionsview函數來顯示正在使用的庫函數的信息,它包含了每一個函數所做用的結構體數據的名字.當鍵入libfunctionsview shrlibsample命令時,matlab就會在新窗口中顯示庫函數的信息。如:double addstructfields (c_struct)2。利用libstruct函數獲取結構體定義模型。如s=libstruct( c_struct);3。繼而利用get函數返回結構體數據的域名。如get(s) p1:0 p2:0 p3:04.利用calllib函數初始化所需要傳遞給庫函數的域值。如s.p1=478; s.p2=299
22、; s。p3=1000; calllib (shrlibsample, addstructfields, s)當你利用calllib函數創(chuàng)建或初始化結構體數據時,不必去匹配結構體的數據域,matlab會自動轉化數據類型.指定結構體域名下面是在為外部庫函數傳遞結構體數據時一般的做法:1。結構體數據可能只包含了定義中很少的一部分域,matlab會把其余的域初始化為0。2.你所使用的任何結構體的域名須與定義中的域名一致。3。結構體中不能包含庫函數中未定義過的域名。傳遞matlab結構體與其他的數據類型一樣,當外部函數接受結構體變量數據類型時,就可以傳遞一個matlab型結構體數據給它.結構體的域名必
23、須與庫函數定義中的域名一致,而數值類型則可以不同,由matlab自動轉換完成。如shrlibsample共享庫中定義了這樣的c結構和函數:struct c_struct double p1; short p2; long p3; ;double addstructfield (struct c_struct st ) double t=st。p1 +st.p2 +st。p3; return t; 下面的代碼完成向addstructfield函數傳遞一個結構體變量sm,包含三個雙精度數據,即傳遞的數值類型與c定義中的不一樣,但域外必須相同,否則傳遞不進去:sm.p1=476; sm。p2=299
24、; sm。p3=1000;calllib(shrlibsample, addstructfields, sm )ans= 1177傳遞結構體對象當為外部函數傳遞結構體變量時,matlab為了確保傳遞成功,要求域名必須與庫函數定義中的一致,而對數值類型則不加強求,由matlab自動轉換成庫函數中對應域的數值類型,并且把空域的值均初始化為零。當結構體數據較小時,這種做法很有效。然而,當重復傳遞一個或多個大的結構體數據時,手動轉化是更明智的選擇,不僅可以節(jié)省時間,還可以節(jié)省內存和空間。使用libstruct函數s=libstruct (structtype, mlstruct)返回值s叫做libst
25、ruct對象。雖然它實際上是matlab的一個對象,但它更象是一個結構體數據.這個新的所謂“結構體的域名得自于外部庫函數中結構體的域名.例如,把matlab結構體sm轉換成libstruct對象sc:sm。p1=476; sm.p2=-299; sm.p3=1000;sc=libstruct (c_struct, sm);sm的原始結構中域值為三個雙精度型,而libstruct函數轉換后的sc對象的域名則與c_struct結構體一致,分別為double、short和long型。創(chuàng)建空libstruct對象s=libstruct (structtype)這種調用格式可以生成域名完整,域值為0的空
26、libstruct對象。使用結構體作為對象libstruct轉換后的結構體實際上是lib。c_struct類中的一個對象實例,這一點可以通過whos命令的輸出來驗證:whos scname size bytes classsc 1by1 lib.c_structgrand total is 1 element using 0 bytes域已經被當成了lib.c_struct類的屬性來處理了。你可以利用基于對象的函數set和get來讀寫:sc=libstruct ( c_struct );set (sc, p1,100, p2, 150, p3, 200 ); 對象讀寫須用get、setget(
27、sc) p1:100 p2:150 p3:200但是你也可以象處理結構體數據那樣簡單地對sc進行讀寫:sc.p1=23; 而結構體的域可以直接賦值sc。p1ans= 23創(chuàng)建形參你可以為外部函數按值傳遞大多數的變量,即使函數原型要求形參傳遞,然而有時你會發(fā)現這與直接給c傳遞形參一樣揍效。使用庫指針函數用函數libpointer構造一個形參的語法如下:p=libpointer(type, value)例如要創(chuàng)建一個指向int16數據類型的指針pv,就得先指定指針的類型,并以ptr作后綴:v=int16(485);pv=libpointer(int16prt, v);返回值pv實際就是matlab
28、中l(wèi)ib。pointer類的一個實例。lib。pointer有屬性值和數據類型。你可以用get或set函數來讀或寫這些屬性.get(pv) value:485datatype:int16ptrlib。pointer類還有另外兩種方法setdatatype和reshape.methods(pv)methods for class lib.pointer:setdatatype reshape為原始類型創(chuàng)建形參如何去創(chuàng)建和傳遞指針給雙精度型,又如何輸出數據這里有一個簡單的例子可以說明。函數multdoubleref接受一個雙精度形參同時返回雙精度型。double multdoubleref(dou
29、ble *x) x =5; return x;輸入數據x來創(chuàng)建一個形參xp: x=15; xp=libpointer(doubleptr,x); get(xp) value:15 datatype:doubleptr現在可以調用函數來檢驗結果:calllib(shrlibsample, multdoubleref, xp);get(xp, value)ans= 75注意:xp雖然是作為x的形參而創(chuàng)建的,但它并非真的象c語言的指針,因為xp中并不包含x的地址,因此,當函數執(zhí)行時,函數修改xp的屬性值,但它并不修改x的值。獲得函數的返回值在上述最后一例子中,從matlab調用的函數返回值可以通過檢
30、查修改了的輸入形參來獲得,但這個函數也可以通過輸出變量來獲得.這個函數的matlab原型表明(利用libfunctions shrlibsample full查看原型),它返回了兩個輸出變量,一為lib.pointer類的對象,另一為dlubleptr輸入變量的屬性值:libfunctions shrlibsample fulllib.pointer, doubleptr multdoubleref (doubleptr)再次運行這個例程,但這次檢查返回值x=15;xp=libpointer( doubleptr, x);xobj, xval=calllib(shrlibsample, mul
31、tdoubleref, xp)xobj= lib.pointerxval= 75創(chuàng)建結構體形參與創(chuàng)建原始類型的形參相比,創(chuàng)建結構體的形參并非難事。下述函數只接受c語言形式的結構體形參,它的返回值是所有結構體域值之和,同時也修改了輸入參量。double addstructbyref( struct c_struct *st ) double t=stp1+stp2+stp3; stp1=5.5; st-p2=1234; stp3=12345678; return t;(1)傳遞結構體本身雖然這個函數期望獲得一個結構體的輸入參量.下列給形參傳遞了一個matlab的結構體sm,返回值是正確的,因為s
32、m不是按址傳遞,所以sm的域值并未被函數修改。sm。p1=476; sm.p2=-299; sm。p3=1000;x=calllib(shrlibsample, addstructbyref, sm)x= 1177(2)傳遞結構體形參sp=libpointer( c_struct, sm);calllib(shrlibsample, addstructbyref, sp )ans= 1177get(sp,value)ans= p1:5.5000 p2:1234 p3:12345678形參指針當變量超過一層引用(例如,uint16 *)就是這里提到的形參指針。在matlab中,這類變量類型都加以
33、后綴ptrptr。當調用一個接受形參指針的函數時,你可以使用一個形參變量代替,matlab將會把該形參變量轉換為形參指針。例如,外部函數allocatestruct接受一個c_structptrptr變量:libfunctions shrlibsample full c_structptrptr allocatestruct(c_structprtptr)c語言編寫的該函數:void allocatestruct (struct c_struct *val) val=(struct c_struct *) malloc(sizeof(sturct c_struct)); (*val)-p1=1
34、2。4; (*val)p2=222; (val)p3=333333;該函數原型需要一個c_structptrptr型數據,但你可以只傳遞一個c_structptr型數據,讓matlab完成第二層引用。下例創(chuàng)建了一個空的結構體形參傳遞給allocatestruct函數:sp=libpointer (c_structptr);calllib( shrlibsample, allocatestruct, sp)get(sp)ans= value:1-by1 struct datatype:c_structptrget(sp, value)ans= p1:12.4000 p2:222 p3:33333
35、3完成之后,記得從內存中刪除該對象以釋放空間:calllib( shrlibsample, deallocatestruct, sp)matlab外部接口你可以在matlab中調用自己編寫的c函數,matlab會讓你感覺就象調用matlab自身內建函數一樣輕松。matlab中可以調用的c函數就是mex文件,mex文件是matlab解釋器能自動加載和執(zhí)行的子程序。mex文件有幾個應用:1。不必為調用大型c程序而把它改寫成matlab默認的m文件。2.解決計算的一些瓶頸問題,在matlab中做一些循環(huán)計算時效率不如c語言。mex文件不適合所有的應用,matlab是一個高效率的系統(tǒng),與c和forta
36、n編譯相比,它能有效降低耗時.一般多數編程matlab均能解決,因此除非你的應用程序確實需要mex文件,否則不必使用mex文件。使用mex文件mex文件是c或fortran代碼的子程序,它的運行就象m文件和內建函數。matlab識別mex文件是根據不同操作平臺文件的擴展名,而m文件的擴展名(。m)與操作平臺無關。不如操作系統(tǒng)下mex文件的擴展名如下:操作系統(tǒng)平臺mex文件擴展名hp-uxmexhpuxlinuxmexglxmacintoshmexmacsolarismexsolwindowsdll你可以準確地調用mex文件就如同調用m文件。例如,磁盤的datafun toolbox目錄上有一conv2。mex的mex文件,它能實現一個二維矩陣的轉換,而conv2.m文件只包含幫助文檔.如果從matlab內部調用函數conv2,解釋器將在matlab的搜索路徑(默認的路徑有多條)上查找,直至找到第一次出現的conv2的文件和相應的擴展名,然后加載并執(zhí)行
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 離婚財產分割合同模板
- 保安公司安保人員聘用合同樣本
- 旅游設施建設報名表
- 建筑腳手架施工合同副本
- 2024年動畫電影配音協議
- 電力設備檢修員聘用合同樣本
- 高三班主任工作計劃(5篇)
- 企業(yè)咨詢服務合同
- 2024年度農業(yè)技術推廣與服務合同
- 企業(yè)總部二手房交易合同模板
- 24秋國家開放大學《0-3歲嬰幼兒的保育與教育》期末大作業(yè)參考答案
- 相對濕度計算公式
- 2024版腫瘤患者靜脈血栓防治指南解讀 課件
- 商業(yè)銀行開展非法集資風險排查活動情況報告
- 英語連讀發(fā)音技巧講解
- 危貨運輸車輛掛靠協議
- 加快推進涉外法治建設
- 綠色供應鏈管理企業(yè)一般要求符合性評價表
- 中航集團招聘筆試題庫2024
- 某系統(tǒng)安防工程施工組織設計方案
- 2024年7月13日云南省昆明市直遴選筆試真題及解析綜合管理崗
評論
0/150
提交評論