matlab 擁有豐富的功能,程式設計簡單。不過,有些情況下,matlab程式的執行速度比較慢。c/c++編譯執行的程式速度比較快,程式設計難度上比matlab要高一些。因此存在一種方案,就是使用matlab實現我們的實驗程式,用c/c++來實現matlab程式中比較耗時的部分,從matlab程式中呼叫c/c++的程式以實現加速。
本文主要講解如何在matlab中呼叫c/c++的程式,以及如何編寫可供matlab程式呼叫的c/c++程式。
本文主要分以下幾部分:
hello matlab,用乙個簡單的例子來說明如何在matlab中呼叫c/c++的程式,以及可供matlab呼叫的c/c++程式應該注意哪些基本事項。
matlab呼叫c/c++程式傳遞引數。討論在c/c++中是如何使用matlab傳來的引數的。
matlab與c/c++混合程式設計的方**。給出在一般情況下使用matlab與c/c++混合程式設計的方法步驟,讓大家有乙個較為清晰的應用此技術的思路。
關於資料儲存的說明。說明資料在matlab中的儲存方式。
注意:本文認為讀者會使用matlab,掌握c/c++語言,並且有一台計算機。計算機上安裝有windows的作業系統,作業系統上裝有matlab以及visual studio(比如vs2008,vs2010等)。或者計算機上安裝有linux的作業系統,系統上裝有matlab,gcc。
我們一步步完成乙個叫「hello matlab」的程式。
第一步:在你的計算機d盤下,建立乙個目錄命名為himat。在d:\himat目錄下建立乙個文字檔案,命名為「abhimat.cpp」。將code 1中的**拷貝到「abhimat.cpp」檔案中,儲存。(注意,這裡建立目錄以及命名等行為不是規定的,只是為了講解方便)。
第一步:在你的計算機d盤下,建立乙個目錄命名為himat。在d:\himat目錄下建立乙個文字檔案,命名為「abhimat.cpp」。將code 1中的**拷貝到「abhimat.cpp」檔案中,儲存
。(注意
,這裡建立目錄以及命名等行為不是規定的,只是為了講解方便)。
[cpp]view plain
copy
print?
#include "mex.h"
void mexfunction (int nlhs, mxarray *plhs, int nrhs, const mxarray *prhs)
#include "mex.h"
void mexfunction (int nlhs, mxarray *plhs, int nrhs, const mxarray *prhs)
code 1, abhimat.cpp
「abhimat.cpp」就是將要在matlab中被呼叫的c/c++**。
第二步:在matlab中編譯「abhimat.cpp」。啟動matlab,進入d:\himat目錄,在matlab命令視窗中執行code 2中的命令,根據提示完成c/c++編譯環境的配置。注意
[plain]view plain
copy
print?
mex -setup
mex -setup
code 2, 設定matlab的c/c++編譯環境
完成配置後,在matlab中執行code 3的命令來編譯abhimat.cpp。
[plain]view plain
copy
print?
mex abhimat.cpp
mex abhimat.cpp
code 3, 編譯abhimat.cpp
第三步:執行編譯後的c/c++程式。在matlab命令視窗輸入「abhimat」或者」abhimat()」,都可以呼叫編譯後的程式,推薦使用後者。
細心的讀者已經注意到了:
此節我們討論下,在供matlab呼叫的c/c++程式中,我們是如何知道matlab呼叫的引數型別、個數的。
給出matlab中呼叫c/c++程式的乙個例項,如code 4所示。
[plain]view plain
copy
print?
c = [1 2;3 4;5 6];
d = [1 1;1 1;1 1];
[a, b] = abfunc(c, d);
c = [1 2;3 4;5 6];
d = [1 1;1 1;1 1];
[a, b] = abfunc(c, d);
code 4, matlab呼叫c/c++程式例項
下面的工作是如何在當前目錄下乙個命名為abfunc.cpp的檔案中實現mexfunction函式。在這個函式中如何獲得matlab命令中的c、d兩個變數的值,如何返回a、b兩個變數呢。
注意mexfunction函式中的四個引數,一一作出說明:
nlhs:mexfunction的第乙個引數,它指示matlab的呼叫命令中等號左側有幾個變數。例如,code 4中的呼叫,nlhs的值為2,因為它的等號左側有兩個變數,他們是a和b。
plhs: mexfunction的第二個引數,它指示matlab的呼叫命令中等號左側變數的指標。例如,code 4中的呼叫,plhs[0]表示的是a,plhs[1]表示的是b。
nrhs:mexfunction的第三個引數,它指示matlab的呼叫命令中等號右側的變數個數。例如,code 4中的呼叫,nrhs的值為2,因為它的等號右側有兩個變數,他們是c和d。
prhs:mexfunction的第四個引數,它指示matlab呼叫命令中等號右側的變數指標。例如,code 4中的呼叫,prhs[0]表示的是c,prhs[1]表示的是d。
mxarrary是乙個不可見的資料型別,是matlab定義的,大家只需要知道mxarrary的指標與matlab中的變數一一對應就可以了。
下面實現abfunc.cpp,功能是a=c+d; b = c-d;具體**如code 5所示。
[cpp]view plain
copy
print?
#include "mex.h"
void mexfunction (int nlhs, mxarray *plhs, int nrhs, const mxarray *prhs)
}
#include "mex.h"
void mexfunction (int nlhs, mxarray *plhs, int nrhs, const mxarray *prhs)
}
code 5, abfunc.cpp的實現
說明一下code 5中用到的函式。這些函式大都以mx開頭。mxassert是斷言,類似於c\c++中的assert。mxgetm獲得matlab傳來的變數的行數,mxgetn獲得matlab傳來的變數的列數。mxcreatedoublematrix建立乙個2維的matlab變數,形參分別用於指定變數的行數、列數、元素型別(mxreal表示實數,mxcomplex表示複數)。mxgetdata用於獲得記憶體中資料塊的首位址。
編譯並測試code 5中的**,參見code 6。
[plain]view plain
copy
print?
mex abfunc.cpp
c = [1 2;3 4;5 6];
d = [1 1;1 1;1 1];
[a, b] = abfunc(c, d);
mex abfunc.cpp
c = [1 2;3 4;5 6];
d = [1 1;1 1;1 1];
[a, b] = abfunc(c, d);
code 6, code5的測試**
code 6的輸出結果如下:
[plain]view plain
copy
print?
a =
2 3
4 5
6 7
b =
0 1
2 3
4 5
a =
2 3
4 5
6 7
b = 0 1
2 3
4 5
matlab中的資料是按列儲存的。例如,a=[1,2;3,4;5,6],a的資料在記憶體中的儲存順序是:1、3、5、2、4、6。在c\c++中使用matlab傳來的變數時,一定要注意資料的儲存順序。
鑑於@程式設計小手 的建議,新增乙個關於使用此方法的方**流程圖。希望它能讓各位明白在什麼情況下可是使用這種混合程式設計的技術、如何一步步實現。參見圖1的流程圖:
圖 1、matlab與c/c++混編方**流程圖
C C 與Matlab混合程式設計初探
分割線以下為正文 matlab 擁有豐富的功能,程式設計簡單。不過,有些情況下,matlab程式的執行速度比較慢。c c 編譯執行的程式速度比較快,程式設計難度上比matlab要高一些。因此存在一種方案,就是使用matlab實現我們的實驗程式,用c c 來實現matlab程式中比較耗時的部分,從ma...
C C 和matlab混合程式設計
有些時候使用混合程式設計能夠讓程式更加高效 筆者所使用的matlab軟體為2018a,c 編譯器為microsoft visual c 2017 matlab本身是不帶c c 編譯器的,安裝編譯軟體是必須的 仍然是先從簡單的hello world 開始 首先編寫乙個c 程式 當然也可以c程式 inc...
matlab和C C 混合程式設計 Mex
最近的專案需要matlab和c的混合程式設計,經過一番努力終於完成了專案要解決的問題。現在就將mex的一些經驗總結一下,當然只是剛剛開始,以後隨著學習的深入繼續新增。首先講講寫mex的一些常規規定,然後我們會重點關注混合程式設計中最難解決資料的問題 結構到底如何轉換,並且後面會重點說一下自己的程式。...