matlab調(diào)用c語言編程_第1頁
matlab調(diào)用c語言編程_第2頁
matlab調(diào)用c語言編程_第3頁
已閱讀5頁,還剩10頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、matlab與C語言混合編程用C編寫mex程序大家都知道,matlab是一種解釋型的編程環(huán)境,也就是說,跟以前的basic 一樣,是讀一句執(zhí)行一句的。這樣做可以很方便的實現(xiàn)編程過程中的交互,也免去了麻煩又耗時的 編譯過程。但凡事有一利必有一弊,matlab在執(zhí)行時速度慢也就根源于此。在matlab里ticfor i=1:10000b(i)=a(10001-i);end怎么樣,是不是很慢?你的程序里如果再多幾個這樣的循環(huán),運行速度就可想而知了。上面程序的功能是將向量a里的數(shù)據(jù)逆序賦給向量b。下面的程序可以實現(xiàn)相同的功能ticb=a(10000:-1:1);為什么這個程序運行速度就這么快呢?這是因

2、為matlab里的基礎(chǔ)矩陣運算函數(shù),像轉(zhuǎn)置,復(fù)制等等,都是以二進制程序的形式存在的,運行起來速度當然比解釋執(zhí)行10000次所以編matlab程序時,應(yīng)該盡量避免用循環(huán)語句,而使用等效的矩陣運算。雖然這樣但總是有的時候沒法找到對應(yīng)的矩陣運算來等效,或編出來的程序復(fù)雜得讓人沒法修簡單地說,mex程序就是根據(jù)一定的接口規(guī)范(matlab提出的)編寫的一個 dll, matla比如我編了一個 mex函數(shù),名字叫max2.dll ,那么只要把這個 dll所在的目錄加到 matlab 的搜索路徑里(用 addpath ),就可以像調(diào)用普通 matlab函數(shù)一樣來調(diào)用它了。因為把 循環(huán)體放到了二進制程序中,

3、執(zhí)行速度快得多。Mex文件既可以用c,也可以用fortran來編。因為我用的是c語言,所以下面的介紹都用c語言編寫mex文件的方法。如果你用的是fortran,請你自己去看 Apiguide.pdf ,里面有詳細說明。前面說到通過把耗時長的函數(shù)用c語言實現(xiàn),并編譯成 mex函數(shù)可以加快執(zhí)行速度。這是Matlab5.1本身是不帶c語言的編譯器的,所以要求你的機器上已經(jīng)安裝有VC,BC或Watcom C中的一種。如果你在安裝Matlab 時已經(jīng)設(shè)置過編譯器,那么現(xiàn)在你應(yīng)該就可以使用mex命令來編譯c語言的程序了。如果當時沒有選,只要在Matlab 里鍵入 mex -setup,就會出現(xiàn)一個 DOS

4、方式窗口,下面只要根據(jù)提示一步步設(shè)置就可以了。由于我用的是w聽說Matlab5.2 已經(jīng)內(nèi)置了 C語言的編譯器,那么下面的這些可能就用不著了??上КF(xiàn) 需要注意的是,在設(shè)置編譯器路徑時,只能使用路徑名稱的8字符形式。比如我用的 VC5裝在路徑 C:PROGRAM FILES'DEVSTUDIO 下,那在設(shè)置路徑時就要寫成: C:PROGRA1示例程序一、這樣設(shè)置完之后,mex就可以執(zhí)行了。為了測試你的路徑設(shè)置正確與否,把下面的程序 存為 hello.c 。#i nclude "mex.h"void mexF unction (i nt n Ihs, mxArray *

5、plhs, int n rhs, const mxArray *prhs)mexPri ntf("hello,world!n");C:假設(shè)你把hello.c放在了下,在Matlab 里用CD C:TEST將當前目錄改為(注意,僅將加入搜索路徑是沒有用的)?,F(xiàn)在敲:mex hello.c如果一切順利,編譯應(yīng)該在出現(xiàn)編譯器提示信息后正常退出。如果你已將加入了搜索路徑,現(xiàn)在鍵入 hello,程序會在屏幕上打出一行: hello,world!看看目錄下,你會發(fā)現(xiàn)多了一個文件:HELLO.DLL。這樣,第一個 mex函數(shù)就算完成了。怎么樣,很簡單吧。下一次,會對這個最簡單的程 序進行

6、分析,并給它增加一些功能。分析hello.c ,可以看到程序的結(jié)構(gòu)是十分簡單的,整個程序由一個接口子過程mexFunction構(gòu)成。前面提到過,Matlab的mex函數(shù)有一定的接口規(guī)范,就是指這nlhs :輸出參數(shù)數(shù)目plhs :指向輸出參數(shù)的指針nrhs :輸入?yún)?shù)數(shù)目例如,使用a,b=test(c,d,e) 調(diào)用mex函數(shù)test時,傳給test的這四個參數(shù)分別是plhs, 3, prhs。其中:prhs0=cprhs1=dprhs2=e當函數(shù)返回時,將會把你放在plhs0,plhs1里的地址賦給a和b,達到返回數(shù)據(jù)的目的。細心的你也許已經(jīng)注意到,prhs和plhs都是指向類型mxArra

7、y類型數(shù)據(jù)的指針。這個類型是在 mex.h中定義的,事實上,在 Matlab里大多數(shù)數(shù)據(jù)都是以這種類型存在。 當然還有其他的數(shù)據(jù)類型,可以參考Apiguide.pdf 里的介紹。為了讓大家能更直觀地了解參數(shù)傳遞的過程,我們把hello.c改寫一下,使它能根據(jù)輸入?yún)?shù)的變化給出不同的屏幕輸出:/hello.c 2.0#include "mex.h"void mexF unction (i nt nl hs, mxArray *plhs, int n rhs, const mxArray *prhs)int i;i=mxGetScalar(prhsO);if(i=1)mexPr

8、i ntf("hello,world!n");elsemexPrintf("大家好! n");將這個程序編譯通過后,執(zhí)行hello(1),屏幕上會打出:hello,world!而hello(0)將會得到:大家好!現(xiàn)在,程序hello已經(jīng)可以根據(jù)輸入?yún)?shù)來給出相應(yīng)的屏幕輸出。在這個程序里,除了用到了屏幕輸出函數(shù) mexPrintf (用法跟c里的printf函數(shù)幾乎完全一樣)外,還用到了一個函數(shù):mxGetScalar ,調(diào)用方式如下:i=mxGetScalar(prhsO);"Scalar"就是標量的意思。在Matlab里數(shù)據(jù)都是以數(shù)

9、組的形式存在的,mxGetScalar的作用就是把通過 prhs0傳遞進來的mxArray 類型的指針指向的 數(shù)據(jù)(標量)賦給C程序里的變量。這個變量本來應(yīng)該是double類型的,通過強制類型轉(zhuǎn)換賦給了整形變量i。既然有標量,顯然還應(yīng)該有矢量,否則矩陣就沒法傳了??聪旅娴某绦颍?hello.c 2.1#include "mex.h"void mexF unction (i nt nl hs, mxArray *plhs, int n rhs, const mxArray *prhs)int *i;i=mxGetPr(prhsO);if(i0=1)mexPri ntf(&qu

10、ot;hello,world!n");elsemexPrintf("大家好! n");這樣,就通過mxGetPr函數(shù)從指向mxArray類型數(shù)據(jù)的prhs0獲得了指向double 類型的指針。但是,還有個問題,如果輸入的不是單個的數(shù)據(jù),而是向量或矩陣,那該怎么處理呢?通過mxGetPr只能得到指向這個矩陣的指針,如果我們不知道這個矩陣的確切大小,就沒法對它進行計算。為了解決這個問題,Matlab提供了兩個函數(shù) mxGetM和mxGetN來獲得傳進來參數(shù)的行數(shù)和列數(shù)。下面例程的功能很簡單,就是獲得輸入的矩陣,把它在屏幕上顯示出來:/show.c 1.0#i nclu

11、de "mex.h"void mexF unction (i nt nl hs, mxArray *plhs, int n rhs, const mxArray *prhs)double *data;int M,N;int i,j;data=mxGetPr(prhsO);/獲得指向矩陣的指針M=mxGetM(prhsO);/獲得矩陣的行數(shù)N=mxGetN(prhsO);/獲得矩陣的列數(shù)for(i=0;i<M;i+)/ i 表示行,j 表示列for(j=0;j<N;j+)mexPri ntf("%4.3f ",data j*M+i);mexPr

12、i ntf("n");編譯完成后,用下面的命令測試一下:a=1:10;b=a;a+1;show(a)show(b)需要注意的是,在 Matlab里,矩陣第一行是從1開始的,而在C語言中,第一行的序 數(shù)為零,Matlab里的矩陣元素b(i,j)在傳遞到C中的一維數(shù)組大 data后對應(yīng)于data j*M+i輸入數(shù)據(jù)是在函數(shù)調(diào)用之前已經(jīng)在Matlab里申請了內(nèi)存的,由于 mex函數(shù)與Matlab共用同一個地址空間,因而在prhs里傳遞指針就可以達到參數(shù)傳遞的目的。但是,輸出參數(shù)卻需要在mex函數(shù)內(nèi)申請到內(nèi)存空間,才能將指針放在plhs中傳遞出 去。由于返回指針類型必須是 mxAr

13、ray ,所以Matlab 專門提供了一個函數(shù): mxCreateDoubleMatrix來實現(xiàn)內(nèi)存的申請,函數(shù)原型如下:mxArray*mxCreateDoubleMatrix(i nt m, int n, mxComplexity ComplexFIag)m :待申請矩陣的行數(shù)n:待申請矩陣的列數(shù)為矩陣申請內(nèi)存后,得到的是mxArray類型的指針,就可以放在plhs里傳遞回去了。但是對這個新矩陣的處理,卻要在函數(shù)內(nèi)完成,這時就需要用到前面介紹的mxGetPr。使用mxGetPr獲得指向這個矩陣中數(shù)據(jù)區(qū)的指針(double類型)后,就可以對這個矩陣進行各種操作和運算了。下面的程序是在上面的s

14、how.c的基礎(chǔ)上稍作改變得到的,功能是將輸入數(shù)據(jù)的每一行倒序復(fù)制給輸出數(shù)據(jù)/reverse.c 1.0#include "mex.h"void mexF unction (i nt nl hs, mxArray *plhs,int n rhs, const mxArray *prhs)double *i nData;double *outData;int M,N;int i,j;in Data=mxGetPr(prhsO);M=mxGetM(prhsO);N=mxGetN(prhsO);plhs0=mxCreateDoubleMatrix(M,N,mxREAL);outD

15、ata=mxGetPr(plhs0);for(i=O;i<M;i+)for(j=0;j<N;j+)outData j*M+i=i nData(N-1-j)*M+i;當然,Matlab里使用到的并不是只有double類型這一種矩陣,還有字符串類型、稀疏矩陣、結(jié)構(gòu)類型矩陣等等,并提供了相應(yīng)的處理函數(shù)。本文用到編制mex程序中最經(jīng)常遇到的一些函數(shù),其余的詳細情況清參考Apiref.pdf 。通過前面兩部分的介紹,大家對參數(shù)的輸入和輸出方法應(yīng)該有了基本的了解。具備了這些知識,就能夠滿足一般的編程需要了。但這些程序還有些小的缺陷,前面的reverse.c中沒有對輸入、輸出參數(shù)的數(shù)目及類型進行

16、檢查,導(dǎo)致程序的容錯性很差。#i nclude "mex.h"void mexF unction (i nt nl hs, mxArray *plhs,int n rhs, const mxArray *prhs)double *i nData;double *outData;int M,N;/異常處理if(n rhs!=1)mexErrMsgTxt("USAGE: b=reverse(a)n");if(!mxlsDouble(prhs0)mexErrMsgTxt("the In put Matrix must be double!n"

17、;);in Data=mxGetPr(prhsO);M=mxGetM(prhsO);N=mxGetN(prhsO);plhs0=mxCreateDoubleMatrix(M,N,mxREAL);outData=mxGetPr(plhs0);for(i=0;i<M;i+)for(j=0;j<N;j+)outData j*M+i=i nData(N-1-j)*M+i;在上面的異常處理中,使用了兩個新的函數(shù):mexErrMsgTxt 和mxIsDouble 。MexErrMsgTxt 在給出出錯提示的同時退出當前程序的運行。MxIsDouble 則用于判斷mxArray 中的數(shù)據(jù)是否do

18、uble類型。當然Matlab還提供了許多用于判斷其他數(shù)據(jù)類型的函數(shù),這里不加詳述。需要說明的是,Matlab 提供的API中,函數(shù)前綴有 mex-和mx-兩種。帶 mx-前綴的大多是對 mxArray 數(shù)據(jù)進行操作的函數(shù),如 mxlsDouble,mxCreateDoubleMatrix等等。而帶 mx前綴的則大多是與 Matlab 環(huán)境進行交互的函數(shù),如mexPrintf , mxErrMsgTxt等等。了解了這一點,對在 Apiref.pdf中查找所需的函數(shù)很有幫助。至此為止,使用 C編寫mex函數(shù)的基本過程已經(jīng)介紹完了。下面會在介紹幾個非常有用的函數(shù)調(diào)用。如果有足夠的時間,也許還會有一個更復(fù)雜一些的例程。我們之所以使用 Matlab,很重要的考慮是 Matlab提供了相當豐富的矩陣運算函數(shù)和各種 toolbox。在編制mex函數(shù)時,有時我們也會遇到一些操作,在Matlab下,只需要一個為了在mex函數(shù)里調(diào)用 Matlab 命令,我們就需要用到一個函數(shù)mexCallMATLAB ,原型如下:int mexCallMATLAB(i nt n Ihs,

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論