衆所周知Matlab的強大運算能力讓各類工程軟件望而卻步,而VC程序的友好界面又讓人愛不釋手,若是可以讓二者的優點結合起來的話,勢必能讓程序員歡欣鼓舞。還好MathWorks已經爲咱們想到了,基本上如今市面上主流的Matlab版本均可以支持VC和Matlab的混合編程。可是目前網上資料基本上都是基於Matlab 6.0和VC 6.0的,和新版本的實現方法有所不一樣,所以筆者經過不斷的嘗試和研究,終於調試通了基於VS2008和Matlab R2010b的混合編程。程序員
爲了更加直觀的說明如何實現混合編程,筆者寫了一個簡單的程序做爲測試。先在Matlab裏面寫一個M文件,代碼以下:redis
function b = MyFunc(a)編程
b = a.*a;數組
將M文件保存爲MyFunc.m,保存在F:/test文件夾中。而後在Matlab主窗口中將當前文件夾改成F:/test:app
cd F:/test;函數
爲了可以讓VC調用Matlab程序,咱們能夠採用將Matlab程序包裝成動態連接文件DLL的形式,而後讓VC調用動態連接文件,所以在Matlab中,咱們須要設置一下Matlab的編譯庫,在Matlab主窗口中鍵入以下代碼:工具
mbuild –setup測試
而後出現ui
Please choose your compiler for building standalone MATLAB applications:指針
Would you like mbuild to locate installed compilers [y]/n?
鍵入y後回車,出現
Select a compiler:
[1] Lcc-win32 C 2.4.1 in D:\PROGRA~1\MATLAB\R2010b\sys\lcc
[2] Microsoft Visual C++ 2008 SP1 in D:\Program Files\Microsoft Visual Studio 9.0
[0] None
Compiler:
因爲咱們是須要用VC來調用Matlab函數,所以咱們選擇2,回車,出現
Please verify your choices:
Compiler: Microsoft Visual C++ 2008 SP1
Location: D:\Program Files\Microsoft Visual Studio 9.0
Are these correct [y]/n?
肯定,鍵入y後回車,出現
****************************************************************************
Warning: Applications/components generated using Microsoft Visual Studio
2008 require that the Microsoft Visual Studio 2008 run-time
libraries be available on the computer used for deployment.
To redistribute your applications/components, be sure that the
deployment machine has these run-time libraries.
****************************************************************************
Trying to update options file: C:\Users\張智宇\AppData\Roaming\MathWorks\MATLAB\R2010b\compopts.bat
From template: D:\PROGRA~1\MATLAB\R2010b\bin\win32\mbuildopts\msvc90compp.bat
Done . . .
若是出現以上說明,則證實Matlab編譯器設置成功了。接下來是生成M文件的DLL文件。
在Matlab主窗口中鍵入以下代碼
mmc –W cpplib:MyDLL –T link:lib MyFunc.m –C
其中cpplib:後面的是須要生成文件的文件名,是本身取的,link:lib後面的MyFunc.m是轉換爲DLL的M文件的文件名。 -W/-T/-C是參數,具體含義能夠經過mcc –help命令查看,注意參數的大小寫。
Matlab編譯後會在Test文件夾下生成9個文件,分別是:
mccEcxludedFiles.log
MyDLL.cpp
MyDLL.ctf
MyDLL.dll
MyDLL.exp
MyDLL.exports
MyDLL.h
MyDLL.lib
readme.txt
其中MyDLL.dll,MyDLL.lib,MyDLL.ctf,MyDLL.h是咱們須要的文件,至此,Matlab方面就已經設置穩當了。
打開VC2008,新建一個工程,而後將上述四個文件複製到工程目錄下。選擇「工具-選項-項目和解決方案-VC++目錄」,在「顯示如下內容目錄」裏選擇「包含文件」將「D:\Program Files\MATLAB\R2010b\extern\include」添加進去,而後選擇「庫文件」將「D:\Program Files\MATLAB\R2010b\extern\lib\win32\microsoft」添加進去,其中D:\Program Files是Matlab的安裝目錄,可根據實際狀況進行修改。
而後選擇「項目-屬性-配置屬性-連接器-輸入」,在右邊「附加依賴項」一欄填入「myDLL.lib mclmcrrt.lib」,其中MyDLL.lib就是剛剛用Matlab生成的lib文件。
在編寫代碼時首先得包含頭文件「MyDLL.h」,而後開始編寫須要的代碼,我爲了說明問題編寫了一個測試代碼以下所示:
{
MyDLLInitialize(); //初始化DLL動態鏈接文件
double _x[5] = {1,2,3,4,5}; //輸入數組
double _y[5]; //輸出數組
mxArray* x = mxCreateDoubleMatrix(1, 5, mxREAL); //建立1*5矩陣
memcpy(mxGetPr(x), (void*)_x, sizeof(_x)); //拷貝輸入數據
mxArray *input[1] = {x}; //將矩陣x的指針做爲輸入參數傳遞進去
mxArray *output[1]; //定義輸出參數指針
mlxMyFunc(1,output,1,input); //調用m函數
mxArray *y; //定義輸出結果指針
y = output[0]; //將輸出參數傳遞給輸出結果
memcpy(_y, mxGetPr(y), sizeof(_y)); //拷貝輸出數據
MyDLLTerminate(); //結束DLL庫
//顯示數組中的數據
CString str;
str.Format("%f %f %f %f %f",_y[0],_y[1],_y[2],_y[3],_y[4]);
MessageBox(str);
}
其中MyDLLInitialize(),mlxMyFunc(),MyDLLTerminate()等函數能夠在MyDLL.h中找到函數原型,mlxMyFunc函數原型爲:
mlxMyFunc(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[])
nlhs表明輸出參數個數,plhs[]裏面存放的是輸出參數的指針,nrhs表明輸入參數個數,prhs[]中存放的是輸入參數的指針。上例中因爲輸入輸出參數只有一個,所以在plhs[0]中存放的就是M文件中b的指針,prhs[0]中存放的就是M文件中a的指針。
編譯運行以後就能夠在彈出的消息框中獲得所要的結果。將項目文件夾下生成的可執行文件複製出來,將MyDLL.dll文件、MyDLL.ctf文件和.exe文件放在同一目錄下即可脫離VC++獨立運行。若是須要在其餘未裝Matlab的機器上運行,則還須要將「D:\Program Files\MATLAB\R2010b\toolbox\compiler\deploy\win32」中的MCRInstaller.exe複製出來,在未安裝Matlab的電腦上運行此程序,纔可以使得剛剛生成的可執行文件順利運行。
以上程序在Windows 7 家庭普通版 + Visual Studio 2008 專業版 SP1 + Matlab R2010b下編譯運行經過。