日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

关于Matlab的MEX技术 10分钟教会你简单的matlab和C/C++混合编程(mex文件)

發布時間:2023/12/20 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于Matlab的MEX技术 10分钟教会你简单的matlab和C/C++混合编程(mex文件) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

10分鐘教會你簡單的matlab和C/C++混合編程(mex文件)

標簽: matlabmexcc++ 379人閱讀 評論(0) 收藏 舉報 本文章已收錄于: 分類: Matlab(4) 作者同類文章X

    最近要用matlab提取視頻的特征,數據量很大,程序跑起來很慢,于是把其中一個模塊改為用C語言來實現。我在這里也記錄一下自己的一些心得。

    我用的編譯器是matlab自帶的Lcc-win32 C 2.4.1編譯器,好處是可以不依賴高級編譯器(如VS、GCC),保證程序只要有matlab即可運行;缺點是只能用C寫,不能使用C++的庫(比如vector、OpenCV)。所以以下這篇文章只適用于針對矩陣、數組(不包括字符串string、元胞cell)的簡單的mex文件編寫。

    用Lcc編譯器編寫mex文件的幾個注意事項:

    1、注釋不能有中文,否則報錯:Specified export _mexFunction is not defined

    2、所有變量定義必須在函數最前面完成,變量沒有定義完,不可以執行其他操作,否則報錯:illegal statement termination


    下面是一個計算矩陣a-b的例子,

    其中mexFunction是默認函數名,不用修改,因為matlab調用的時候用的是mex的文件名,而不是函數名。

    nlhs代表的是輸出參數的個數

    plhs是一個指針數組,里面的指針指向mxArray類型,每一個指針指向一個輸出

    nrhs代表的是輸入參數的個數

    prhs是一個指針數組,里面的指針指向mxArray類型,每一個指針指向一個輸入


    [cpp] view plaincopyprint?
  • #include?"mex.h"??
  • #include?"matrix.h"??
  • //?b?=?[1?2;3?4]??
  • //?a?=?[5?6;7?8]??
  • //?c?=?mex_func(a(:),?b,?size(a,1))??%?attention?!?a?is?a(:)???
  • void?mexFunction?(int?nlhs,?mxArray?*plhs[],?int?nrhs,?const?mxArray?*prhs[])??
  • {??
  • ??double?*data1?=?mxGetPr(prhs[0]);??//get?pointer?of?a(is?a?vector)??
  • ??double?*data2?=?mxGetPr(prhs[1]);??//get?pointer?of?b(is?a?matrix)??
  • ????
  • ??int?data1_num?=?mxGetM(prhs[0]);???//?get?elements?num?of?data1??????
  • ??int?data1_h?=?mxGetScalar(prhs[2]);//get?height?of?matrix?a??
  • ??int?data1_w?=?data1_num/data1_h;???//calculate?the?width?of?matrix?a??
  • ??//?the?step?above?is?no?need?when?dealing?with?2D?matrix???
  • ??
  • ??int?data2_h?=?mxGetM(prhs[1]);//?get?rows?of?data2??
  • ??int?data2_w?=?mxGetN(prhs[1]);//?get?cols?of?data2??
  • ???????????
  • ??int?output_h?=?data1_h;??
  • ??int?output_w?=?data1_w;??
  • ????
  • ??int?i,j;??
  • ??double?**copy_array;//?pointer?of?mid-data??
  • ??double?*y;??
  • ??//end?variable?defination,?all?the?defination?shoule?be?set?at?the?beginning??
  • ??//******************************************************??
  • ???
  • ??if?((data1_h!=data2_h)||(data1_w!=data2_w)){??
  • ????printf("matrix?dim?not?matched!\n");??
  • ??}??
  • ??//setup?mid-data??
  • ??copy_array?=?(double?**)malloc(sizeof(double?*)?*?output_h);??
  • ??for(i=0;?i<output_h;i++){??
  • ??????copy_array[i]?=?(double?*)malloc(sizeof(double)?*?output_w);??????????
  • ??}??
  • ??//?calculate?matrix?a-b??
  • ??for?(i=0;?i<output_h;?i++){????
  • ????????for?(j=0;?j<output_w;j++){??
  • ??????????????copy_array[i][j]?=?data1[i+j*data1_h]?-?data2[i+j*data2_h];????
  • ????????}??
  • ??}??
  • ??//end?calculating??
  • ??//*******************************************************??
  • ??plhs[0]?=?mxCreateDoubleMatrix(output_h,output_w,?mxREAL);??
  • ??y?=?mxGetPr(plhs[0]);??
  • ??//copy?the?mid-data?to?the?output?pointer??
  • ??for?(i=0;i<output_h;i++){??
  • ??????for(j=0;j<output_w;j++){??
  • ??????????*(y+i+j*output_h)=copy_array[i][j];??
  • ??????}??
  • ????}??
  • ????
  • }??
  • #include "mex.h" #include "matrix.h" // b = [1 2;3 4] // a = [5 6;7 8] // c = mex_func(a(:), b, size(a,1)) % attention ! a is a(:) void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {double *data1 = mxGetPr(prhs[0]); //get pointer of a(is a vector)double *data2 = mxGetPr(prhs[1]); //get pointer of b(is a matrix)int data1_num = mxGetM(prhs[0]); // get elements num of data1 int data1_h = mxGetScalar(prhs[2]);//get height of matrix aint data1_w = data1_num/data1_h; //calculate the width of matrix a// the step above is no need when dealing with 2D matrix int data2_h = mxGetM(prhs[1]);// get rows of data2int data2_w = mxGetN(prhs[1]);// get cols of data2int output_h = data1_h;int output_w = data1_w;int i,j;double **copy_array;// pointer of mid-datadouble *y;//end variable defination, all the defination shoule be set at the beginning//******************************************************if ((data1_h!=data2_h)||(data1_w!=data2_w)){printf("matrix dim not matched!\n");}//setup mid-datacopy_array = (double **)malloc(sizeof(double *) * output_h);for(i=0; i<output_h;i++){copy_array[i] = (double *)malloc(sizeof(double) * output_w); }// calculate matrix a-bfor (i=0; i<output_h; i++){ for (j=0; j<output_w;j++){copy_array[i][j] = data1[i+j*data1_h] - data2[i+j*data2_h]; }}//end calculating//*******************************************************plhs[0] = mxCreateDoubleMatrix(output_h,output_w, mxREAL);y = mxGetPr(plhs[0]);//copy the mid-data to the output pointerfor (i=0;i<output_h;i++){for(j=0;j<output_w;j++){*(y+i+j*output_h)=copy_array[i][j];}}}


    簡單總結一下幾個要點:

    mex文件的編寫可以分為三個步驟,數據傳入,數據處理,數據導出

    1、傳入矩陣用mxGetPr,傳入數值用mxGetScalar

    2、獲取2維矩陣維度用mxGetM,mxGetN,C模塊無法同時獲得3維矩陣的三個維度,維度需要自己手動傳遞

    此處有誤,可以用函數mxGetDimensions: 就是返回一個指針ptr,每一個指針所指向的值是每一個維度的元素個數。例如有矩陣3*2的矩陣,那么*(ptr)為3,*(ptr+1)為2,如果是3維矩陣,只需要訪問*(ptr+2)。參考文章中的第四節有詳細描述)

    3、數據在內存上都是連續的,訪問的時候按列的順序訪問

    4、數據傳出用mxCreateDoubleMatrix,先創建一個double類型的指針用來存放要導出的數據,然后再拷貝到plhs[i]對應的指針上

    參考文章:matlab和C/C++混合編程--Mex

    0
    0


    關于Matlab的MEX技術??


    2008-03-30 15:13:58|??分類: CAE |??標簽: |舉報 |字號?訂閱


    ? ? ? ?

    用微信??“掃一掃”

    將文章分享到朋友圈。

    用易信??“掃一掃”

    將文章分享到朋友圈。

    下載LOFTER 我的照片書??|




    MEX文件的功能主要包括三個方面(參見文獻[1]),這里主要是將Matlab作為CFortran代碼的調試器。以下工作的軟件平臺為:

    l??????? Microsoft.Visual.Studio.2005.Professional.Edition.DVD

    l??????? Intel.Visual.Fortran.Compiler.Pro.v9.1.032

    l??????? Matlab 7.5.0(R2007b)

    Matlab自帶的timestwo.c文件為例(C:\Program Files\MATLAB\R2007b\extern\examples\refbook\timestwo.c)說明MEX的工作流程:用戶在Matlab命令行(主界面中的Command Window)下輸入:

    mex timestwo.c

    如果編譯順利完成,同文件夾下會出現一個名為“timestwo.mexw32的文件(Matlab版本為R2007b),再在Matlab命令行下輸入:

    timestwo(5.5)

    輸出為:

    ans=

    11

    表示這個函數計算結果正確。要注意C文件的文件名必須是算法函數的函數名(這里二者都是timestwo)(這一條似乎不必要)。

    制作C-MEX文件的具體步驟:

    1.????? 修改原C代碼。
    原算法函數不需要修改,但需要新增一個名為mexFunction的函數,另外在文件頭部增加“#include "mex.h"”。工作量體現在寫mexFunction函數上。當用戶輸入“timestwo(5.5)”時,Matlab首先進入這個函數,這個函數再調用原算法函數,給出答案。因此對用戶輸入、輸出格式是否正確的檢驗是在該函數中完成的。另外可以看到,原C函數格式是void fun(y,x),但在Matlab中使用時格式是y=fun(x),這說明mexFunction函數對輸入、輸出格式可以自由定義。詳細的寫法參見文獻[1]4.3節。

    2.????? Matlab中將C編譯為MEX文件(如前文所述)。

    3.????? 使用這個MEX文件(如前文所述)。另外只要這個timestwo.mexw32文件在當前目錄下,關閉Matlab后重新啟動仍可以直接使用timestwo函數。

    如果要編譯Fortran文件,先用mex setup將編譯器改為Fortran的編譯器,然后用同樣的方法編譯即可。

    參考文獻:

    [1] 楊高波.精通matlab7.0混合編程.電子工業出版社,2006






    ? 評論這張


    轉發至微博



    轉發至微博


    閱讀(2063)| 評論(0) | ? ? ? ?

    用微信??“掃一掃”

    將文章分享到朋友圈。

    用易信??“掃一掃”

    將文章分享到朋友圈。

    推薦 0??|? 轉載


    ? 用Matlab驗證DataFit軟件給出的插值函數的正確性 ? Fortran-MEX調試方法















    總結

    以上是生活随笔為你收集整理的关于Matlab的MEX技术 10分钟教会你简单的matlab和C/C++混合编程(mex文件)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。