mexsetup編譯器
㈠ 如何讓matlab用mex與C連接使用有例子 PDF
如果我有一個用c語言寫的函數,實現了一個功能,如一個簡單的函數:
double add(double x, double y)
{ return x + y; }
現在我想要在Matlab中使用它,比如輸入:
>> a = add(1.1, 2.2)
3.3000
要得出以上的結果,那應該怎樣做呢?
解決方法之一是要通過使用MEX文件,MEX文件使得調用C函數和調用Matlab的內置函數一樣方便。MEX文件是由原C代碼加上MEX文件專用的介面函數後編譯而成的。可以這樣理解,MEX文件實現了一種介面,它把在Matlab中調用函數時輸入的自變數通過特定的介面調入了C函數,得出的結果再通過該介面調回Matlab。該特定介面的操作,包含在mexFunction這個函數中,由使用者具體設定。
所以現在我們要寫一個包含add和mexFunction的C文件,Matlab調用函數,把函數中的自變數(如上例中的1.1和2.2)傳給 mexFunction的一個參數,mexFunction把該值傳給add,把得出的結果傳回給mexFunction的另一個參數,Matlab通過該參數來給出在Matlab語句中調用函數時的輸出值(如上例中的a)。
值得注意的是,mex文件是與平台有關的,以我的理解,mex文件就是另類的動態鏈接庫。在matlab6.5中使用mex -v 選項,你可以看到最後mex階段有類似如下的信息:
--> "del _lib94902.obj"
--> "del "test.exp""
--> "del "test.lib""
也就是說,雖然在matlab6.5生成的是dll文件,但是中間確實有過lib文件生成。
比如該C文件已寫好,名為add.c。那麼在Matlab中,輸入:
>> mex add.c
就能把add.c編譯為MEX文件(編譯器的設置使用指令mex -setup),在Windows中,MEX文件類型為mexw32,即現在我們得出add.mexw32文件。現在,我們就可以像調用M函數那樣調用 MEX文件,如上面說到的例子。所以,通過MEX文件,使用C函數就和使用M函數是一樣的了。
我們現在來說mexFunction怎樣寫。
mexFunction的定義為:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
}
可以看到,mexFunction是沒返回值的,它不是通過返回值把結果傳回Matlab的,而是通過對參數plhs的賦值。mexFunction的四個參數皆是說明Matlab調用MEX文件時的具體信息,如這樣調用函數時:
>> b = 1.1; c = 2.2;
>> a = add(b, c)
mexFunction四個參數的意思為:
nlhs = 1,說明調用語句左手面(lhs-left hand side)有一個變數,即a。
nrhs = 2,說明調用語句右手面(rhs-right hand side)有兩個自變數,即b和c。
plhs是一個數組,其內容為指針,該指針指向數據類型mxArray。因為現在左手面只有一個變數,即該數組只有一個指針,plhs[0]指向的結果會賦值給a。
prhs和plhs類似,因為右手面有兩個自變數,即該數組有兩個指針,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指針數組,即不能改變其指向內容。
因為Matlab最基本的單元為array,無論是什麼類型也好,如有double array、 cell array、 struct array……所以a,b,c都是array,b = 1.1便是一個1x1的double array。而在C語言中,Matlab的array使用mxArray類型來表示。所以就不難明白為什麼plhs和prhs都是指向mxArray類型的指針數組。
完整的add.c如下:
#include "mex.h" // 使用MEX文件必須包含的頭文件
// 執行具體工作的C函數
double add(double x, double y)
{
return x + y;
}
// MEX文件介面函數
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
{
double *a;
double b, c;
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
a = mxGetPr(plhs[0]);
b = *(mxGetPr(prhs[0]));
c = *(mxGetPr(prhs[1]));
*a = add(b, c);
}
mexFunction的內容是什麼意思呢?我們知道,如果這樣調用函數時:
>> output = add(1.1, 2.2);
在未涉及具體的計算時,output的值是未知的,是未賦值的。所以在具體的程序中,我們建立一個1x1的實double矩陣(使用 mxCreateDoubleMatrix函數,其返回指向剛建立的mxArray的指針),然後令plhs[0]指向它。接著令指針a指向plhs [0]所指向的mxArray的第一個元素(使用mxGetPr函數,返回指向mxArray的首元素的指針)。同樣地,我們把prhs[0]和prhs [1]所指向的元素(即1.1和2.2)取出來賦給b和c。於是我們可以把b和c作自變數傳給函數add,得出給果賦給指針a所指向的mxArray中的元素。因為a是指向plhs[0]所指向的mxArray的元素,所以最後作輸出時,plhs[0]所指向的mxArray賦值給output,則 output便是已計算好的結果了。
上面說的一大堆指向這指向那,什麼mxArray,初學者肯定都會被弄到頭暈眼花了。很抱歉,要搞清楚這些亂糟糟的關系,只有多看多練。
實際上mexFunction是沒有這么簡單的,我們要對用戶的輸入自變數的個數和類型進行測試,以確保輸入正確。如在add函數的例子中,用戶輸入char array便是一種錯誤了。
從上面的講述中我們總結出,MEX文件實現了一種介面,把C語言中的計算結果適當地返回給Matlab罷了。當我們已經有用C編寫的大型程序時,大可不必在 Matlab里重寫,只寫個介面,做成MEX文件就成了。另外,在Matlab程序中的部份計算瓶頸(如循環),可通過MEX文件用C語言實現,以提高計算速度。
以上是對mex文件的初步認識,下面詳細介紹如何用c語言編寫mex文件:
1 為什麼要用C語言編寫MEX文件
MATLAB是矩陣語言,是為向量和矩陣操作設計的,一般來說,如果運算可以用向量或矩陣實現,其運算速度是非常快的。但若運算中涉及到大量的循環處理,MATLAB的速度的令人難以忍受的。解決方法之一為,當必須使用for循環時,把它寫為MEX文件,這樣不必在每次運行循環中的語句時MATLAB都對它們進行解釋。
2 編譯器的安裝與配置
要使用MATLAB編譯器,用戶計算機上應用事先安裝與MATLAB適配的以下任何一種ANSI C/C++編譯器:
5.0、6.0版的MicroSoft Visual C++(MSVC)
5.0、5.2、5.3、5.4、5.5版的Borland C++
LCC(由MATLAB自帶,只能用來產生MEX文件)
下面是安裝與配置MATLAB編譯器應用程序MEX的設置的步驟:
(1)在MATLAB命令窗口中運行mex –setup,出現下列提示:
Please choose your compiler for building external interface (MEX) files:
Would you like mex to locate installed compilers [y]/n?
(2)選擇y,MATLAB將自動搜索計算機上已安裝的外部編譯器的類型、版本及所在路徑,並列出來讓用戶選擇:
Select a compiler:
[1] Borland C++Builder version 6.0 in C:\Program Files\Borland
[2] Digital Visual Fortran version 6.0 in C:\Program Files\Microsoft Visual Studio
[3] Lcc C version 2.4 in D:\MATLAB6P5P1\sys\lcc
[4] Microsoft Visual C/C++ version 6.0 in C:\Program Files\Microsoft Visual Studio
[0] None
Compiler:
(3)選擇其中一種(在這里選擇了3),MATLAB讓用戶進行確認:
Please verify your choices:
Compiler: Lcc C 2.4
Location: D:\MATLAB6P5P1\sys\lcc
Are these correct?([y]/n):
(4)選擇y,結束MATLAB編譯器的配置。
3 一個簡單的MEX文件例子
【例1】用m文件建立一個1000×1000的Hilbert矩陣。
tic
m=1000;
n=1000;
a=zeros(m,n);
for i=1:1000
for j=1:1000
a(i,j)=1/(i+j);
end
end
toc
在matlab中新建一個Matlab_1.cpp 文件並輸入以下程序:
#include "mex.h"
//計算過程
void hilb(double *y,int n)
{
int i,j;
for(i=0;i
for(j=0;j
*(y+j+i*n)=1/((double)i+(double)j+1);
}
//介面過程
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
{
double x,*y;
int n;
if (nrhs!=1)
mexErrMsgTxt("One inputs required.");
if (nlhs != 1)
mexErrMsgTxt("One output required.");
if (!mxIsDouble(prhs[0])||mxGetN(prhs[0])*mxGetM(prhs[0])!=1)
mexErrMsgTxt("Input must be scalars.");
x=mxGetScalar(prhs[0]);
plhs[0]=mxCreateDoubleMatrix(x,x,mxREAL);
n=mxGetM(plhs[0]);
y=mxGetPr(plhs[0]);
hilb(y,n);
}
該程序是一個C語言程序,它也實現了建立Hilbert矩陣的功能。在MATLAB命令窗口輸入以下命令:mex Matlab_1.cpp,即可編譯成功。進入該文件夾,會發現多了兩個文件:Matlab_1.asv和Matlab_1.dll,其中Matlab_1.dll即是MEX文件。運行下面程序:
tic
a=Matlab_1(1000);
toc
elapsed_time =
0.0470
由上面看出,同樣功能的MEX文件比m文件快得多。
4 MEX文件的組成與參數
MEX文件的源代碼一般由兩部分組成:
(1)計算過程。該過程包含了MEX文件實現計算功能的代碼,是標準的C語言子程序。
(2)入口過程。該過程提供計算過程與MATLAB之間的介面,以入口函數mxFunction實現。在該過程中,通常所做的工作是檢測輸入、輸出參數個數和類型的正確性,然後利用mx-函數得到MATLAB傳遞過來的變數(比如矩陣的維數、向量的地址等),傳遞給計算過程。
MEX文件的計算過程和入口過程也可以合並在一起。但不管那種情況,都要包含#include "mex.h",以保證入口點和介面過程的正確聲明。注意,入口過程的名稱必須是mexFunction,並且包含四個參數,即:
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
其中,參數nlhs和nrhs表示MATLAB在調用該MEX文件時等式左端和右端變數的個數,例如在MATLAB命令窗口中輸入以下命令:
[a,b,c]=Matlab_1(d,e,f,g)
則nlhs為3,nrhs為4。
MATLAB在調用MEX文件時,輸入和輸出參數保存在兩個mxArray*類型的指針數組中,分別為prhs[]和plhs[]。prhs[0]表示第一個輸入參數,prhs[1]表示第二個輸入參數,…,以此類推。如上例中,d→prhs[0],e→prhs[1],f→prhs[2],f→prhs[3]。同時注意,這些參數的類型都是mxArray *。
介面過程要把參數傳遞給計算過程,還需要從prhs中讀出矩陣的信息,這就要用到下面的mx-函數和mex-函數。
5 常用的mex-函數和mx-函數
在MATLAB6.5版本中,提供的mx-函數有106個,mex-函數有38個,下面我們僅介紹常用的函數。
5.1入口函數mexFunction
該函數是C MEX文件的入口函數,它的格式是固定的:
void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
說明:MATLAB函數的調用方式一般為:[a,b,c,…]=被調用函數名稱(d,e,f,…),nlhs保存了等號左端輸出參數的個數,指針數組plhs具體保存了等號左端各參數的地址,注意在plhs各元素針向的mxArray內存未分配,需在介面過程中分配內存;prhs保存了等號右端輸入參數的個數,指針數組prhs具體保存了等號右端各參數的地址,注意MATLAB在調用該MEX文件時,各輸入參數已存在,所以在介面過程中不需要再為這些參數分配內存。
㈡ 如何設置matlab 編譯器 mex
mex -setup
Please choose your compiler for building external interface (MEX) files:
Would you like mex to locate installed compilers [y]/n? y
Select a compiler:
[1] Lcc-win32 C 2.4.1 in D:\Programs\MATLAB\R2010a\sys\lcc
[2] Microsoft Visual C++ 2005 SP1 in D:\Program Files\Microsoft Visual Studio 8
[3] Microsoft Visual C++ 6.0 in C:\Program Files\Microsoft Visual Studio
[0] None
Compiler: 2
Please verify your choices:
Compiler: Microsoft Visual C++ 2005 SP1
Location: D:\Program Files\Microsoft Visual Studio 8
Are these correct [y]/n? y
Trying to update options file: C:\Documents and Settings\Administrator\Application Data\MathWorks\MATLAB\R2010a\mexopts.bat
From template: D:\Programs\MATLAB\R2010a\bin\win32\mexopts\msvc80opts.bat
Done . . .
**************************************************************************
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the new
API. You can find more information about this at:
http://www.mathworks.com/support/solutions/en/data/1-5C27B9/?solution=1-5C27B9
Building with the -largeArrayDims option enables the new API.
**************************************************************************
㈢ MATLAB 如何配置編譯器
在MATLAB的Command Window下輸入命令 mbuild –setup,並根據MATLAB的提示選擇合適的編譯器,使用Microsoft Visual C++6.0,進行對C++連接環境的設置。
過程如下:
>> mbuild -setup
按照提示選擇操作,選擇編譯器進行安裝
然後,在MATLAB的Command Window下輸入命令 mex –setup,進行對編譯環境的設置。過程如下:
>> mex -setup
按照提示選擇操作,選擇你所需要的編譯器就可以了。
㈣ 設置MATLAB和AMESIM的聯合模擬的介面時出現的問題
總體思路:設定篩選條件,將數組中符合條件的元素篩選出來(可以篩選出元素值也可以篩選出元素對應的下標),然後將元素值賦值給另外一個數組的元素
參考代碼:
clc
clear all
close all
x = randi(10, 1, 5); % 原始數據
disp('x=');
disp(x);
y1 = -1 * ones(1, length(x)); % 存儲篩選出的結果,並初始化成不可能出現的結果
%-- 篩選符合條件的元素下標,並將對應元素存到y1 --%
ix = find(x>=3); % 例如,篩選出原始數據中大於3的元素的下標
if(isempty(ix))
disp('x的元素均不符合條件');
else
y1(1:length(ix)) = x(ix); % 將符合條件的元素存到y1中
y1( find(y1==-1) ) = []; % 剩餘元素刪除
disp('y1=');
disp(y1);
end
%----------------------------------------------%
y2 = -1 * ones(1, length(x)); % 存儲篩選出的結果,並初始化成不可能出現的結果
%-- 篩選符合條件的元素值,並存入y2 --%
for i=1:length(x)
if(x(i)>=3) % 逐個檢測x的元素是否符合條件,把符合條件的元素值賦值給y2
y2(i) = x(i);
end
end
y2( find(y2==-1) ) = []; % 剩餘元素刪除
disp('y2=');
disp(y2);
%----------------------------------%
輸出結果
x=
7 1 9 10 7
y1=
7 9 10 7
y2=
7 9 10 7
㈤ 在matlab中鍵入mex -setup,出現Error using ==> mex at 218,(Directory access failure)怎麼解決
刪除環境變數中 用戶變數里的TMP 、TEMP和%TEMP 三個試試~~~~ 我的是在matlab中鍵入mex -setup,出現Error using ==> mex at 208 那樣解決了
㈥ matlab 中mex -setup 編譯器怎麼弄
這個需要你的電腦上安裝有C++6.0才能出來,mex -setup列出的編譯器都是你電腦上的,你圖上的[1] Lcc-win32是matlab自帶的編譯器。
由於你電腦上沒安裝其他的編譯器,當然就檢測不到C++6.0
㈦ truetime安裝問題
中間少了一步:
輸入mex -setup,選擇編譯器,然後
輸入make_truetime,看編譯器是否能編譯(我就遇到了不能編譯的情況),
最後再輸入truetime.才能調用truetime工具。
另外,在這操作之前的一些步驟也網上都有,查下
㈧ MATLAB mex 找不到編譯器
①選y後,MATLAB會列出當前機器上已經安裝的、且與當前MATLAB版本兼容的所有C編譯器,一般而言,MATLAB都會自帶一個LCC編譯器,然而LCC目前僅支持32位的MATLAB,所以你的機器上沒有;
②選n後,MATLAB會列出所有與當前MATLAB版本兼容的C編譯器類型(不管你是否已經安裝,用於幫助用戶選擇合適的C編譯器),你機器上已經安裝的2個編譯器,VC6.0:MATLAB從R2010b之後不再支持,所以選項里看不到;而SDK7.1選n時可以看到([11]),但選y時沒有跳出,是因為MATLAB沒有正確定位SDK;
③解決方法:
方法一:如果以預設選項安裝了SDK7.1(不改變默認安裝路徑),可以嘗試輸入n後,選擇 [14] (注意:是14,不是11!),強制定位該編譯器(網上有人用這種方法成功了:http://mlinking.blog.163.com/blog/static/185801922201331464626365/)
方法二:重新安裝MATLAB,安裝時選擇32位進行安裝,則自帶LCC編譯器;
方法三:選擇適配的VS版本,下載安裝後,重新配置MEX命令
㈨ matlab mex 編譯器怎麼編譯文件
通過MEX文件可以在MATLAB中像調用內嵌函數一樣調用現有的使用C語言和Fortran等語言編寫的函數,實現了代碼重用,同時也能解決MATLAB循環效率低的缺點,提高MATLAB環境中數據處理的效率。
MEX文件的後綴名為 .mexw32
MEX文件的編寫和編譯需要兩個基本條件:一是必須按照MATLAB應用程序介面組件和相關工具,二是要有C語言或Fortran語言的編譯器。
需要對MATLAB系統進行設置,使MATLAB系統知道使用系統的哪一個C語言編譯器,以及其參數和路徑。
MEX文件系統設置:
>> mex –setup按照提示進行,最後出現Done…系統配置完畢。
C語言MEX文件的建立
C語言MEX文件的建立
1. MEX文件的結構
a) 計運算元程序
b) 入口子程序,void mexFunction(int nlhs, mxArray *plhs[],int nrhs,const mxArray *prhs[]){ /*用戶特定的代碼….*/ }
2. 創建timestwoalt.c
#include "mex.h"
void timestwo_alt(double *y, double x)
{
*y = 2.0*x;
}
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[] )
{
double *y;
doublex;
/* 檢查參數 */
if (nrhs != 1) {
mexErrMsgTxt("One input argument required.");
} else if (nlhs > 1) {
mexErrMsgTxt("Too many output arguments.");
} else if (!mxIsNumeric(prhs[0])) {
mexErrMsgTxt("Argument must be numeric.");
} else if (mxGetNumberOfElements(prhs[0]) != 1 || mxIsComplex(prhs[0])) {
mexErrMsgTxt("Argument must be non-complex scalar.");
}
/* 為輸出參數創建變數 */
plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
/*
為參數 x、y賦值,x為值,而y為指針
(由於MATLAB沒有值傳遞,所以用指針才能得到修改後的y值,
不然修改的是y的一個副本,為臨時變數,在函數返回時,y值沒有變化,
不能得到希望的結果)
*/
x = mxGetScalar(prhs[0]);
y = mxGetPr(plhs[0]);
/* 調用timestwo_alt 子函數 */
timestwo_alt(y,x);
}
3. 編譯鏈接C語言的MEX文件源程序,在MATLAB的控制窗口中輸入:mex timestwoalt.c生成一個名為timestwoalt.mexw32的MEX文件
4. 運行:在MATLAB的控制窗口中輸入
x=2;
y=timestwoalt(x)
輸出:y=4
MEX文件實現了一種C語言與MATLAB的介面,其實際的計算功能仍在C語言形式的計運算元程序中完成,而入口子程序的功能是檢查參數以匹配C語言的參數規范(how to?)。
當有C語言編寫的大型程序時,不必用MATLAB語言重新編寫,只要將此C語言程序作為一個計運算元程序,然後編寫一個入口子程序,完成參數的匹配,然後編譯成MEX文件即可。
MEX文件的另外一個功能是可以將MATLAB編程中的瓶頸問題,如多重循環等,將此類費時的指令用C語言實現,然後作必要的入口子程序,編譯成MEX文件,可以有效地提高MATLAB的效率。
S-函數創建器限制了C語言S-函數的功能:只能有一個輸入信號和一個輸出信號,而且只能處理double類型的數據!所以,可用性不大。
㈩ 用MATLAB如何與C++連接
Matlab 是當前應用最為廣泛的數學軟體,具有強大的數值計算、數據分析處理、系統 分析、圖形顯示甚至符號運算等功能[1]。利用這一完整的數學平台,用戶可以快速實現十分 復雜的功能,極大地提高工程分析計算的效率[2][3]。但與其他高級程序[3]相比,Matlab 程序 是一種解釋執行程序,不用編譯等預處理,程序運行速度較慢[4]。
C/C++語言是目前最為流行的高級程序設計語言之一[5]。它可對操作系統和應用程序以 及硬體進行直接操作,用C/C++語言明顯優於其它解釋型高級語言,一些大型應用軟體如 Matlab 就是用C 語言開發的。
在工程實踐中,用戶經常遇到Matlab 與C/C++混合編程的問題。本文基於Matlab 6.5和VC6.0 開發環境,在Windows 平台下就它們之間的混合編程問題進行深入研究並舉例說明。
2 Matlab 調用C/C++
Matlab 調用C/C++的方式主要有兩種:利用MEX 技術和調用C/C++動態連接庫。
在Matlab 與C/C++混合編程之前,必須先對Matlab 的編譯應用程序mex 和編譯器mbuild進行正確的設置[1]:
對Matlab 編譯應用程序mex 的設置:Mex –setup.
對Matlab 編譯器mbuild 的設置:Mbuild –setup.
2.1 調用C/C++的MEX 文件
MEX 是Matlab Executable 的縮寫,它是一種「可在Matlab 中調用的C(或Fortran)語 言衍生程序」[6]。MEX 文件的使用極為方便,其調用方式與Matlab 的內建函數完全相同,只 需在Matlab 命令提示符下鍵入MEX 文件名即可。
一個C/C++的MEX源程序通常包括4個組成部分,其中前3個是必須包含的內容,第4個則根據所實現的功能靈活選用:(1)#include 「mex.h」;(2)MEX文件的入口函數mexFunction, MEX文件導出名必須為mexFunction函數;(3)mxArray;(4)API函數