原文位址:http://blog.chinaunix.net/uid-20776117-id-1847019.html
在C、C++中調用Matlab
Matlab是美國MathWorks公司的産品,是一種以矩陣為基本程式設計機關的高效數值計算語言。Matlab集科學計算、圖像處理、聲音處理于一體,為使用者提供了豐富的Windows圖形界面設計方法,使使用者能夠在利用其強大數值計算功能的同時設計出友好的圖形界面
。Matlab已經被證明是在應用數學、實體、工程學和其它涉及複雜數值計算等應用領域中解決問題的優秀工具。Matlab能夠在Win95/98、Win2000、Linux和Unix等多種作業系統平台上運作。
C、C++是衆多程式員十分喜愛的進階程式設計語言,但其在數值處理分析和算法工具等方面,效率遠遠低于Matlab 語言;在準确友善地繪制資料圖形方面,Matlab 語言具有C和C++無法比拟的優勢。但Matlab作為一種以解釋方式運作的計算機語言,其程式的執行效率較低,而且不能實作端口操作和實時控制。是以,若能将兩者結合運用,實作優勢互補,将獲得極大的效益。為此,MathWorks公司提供了Matlab和C、C++的接口。通過接口,使用者既可在C程式中調用Matlab的函數,也可在Matlab中調用C或C++程式,進而實作Matlab和C、C++的混合程式設計。本文主要讨論如何在C、C++中調用Matlab。
一、過程分析
在C、C++中調用Matlab的主要過程如下所示:
1) 首先調用engOpen函數打開一個Matlab工程。
2) 生成mxArray。
在Matlab中,所有變量類型,如标量、向量、矩陣、字元串、細胞矩陣和結構,都以mxArrays形式來儲存,固資料操作都必須通過這些mxArrays來完成。生成mxArray有兩種不同的方式。一是用mxCreate函數來建立矩陣,之後用mxSetName函數對它進行命名。
另一種方式是選擇将一個自定義的資料結構複制到mxArray中,值得注意的是Matlab在存儲矩陣時是按列序儲存的,而在C、C++中是按行序儲存的,是以轉換時注意厘清下标。
3) 調用engPutArray函數将矩陣放入到Matlab工作區中。
4) 通過engEvalString函數向Matlab傳遞指令,如果成功,函數傳回值為此0,否則傳回一個非0值。
5) 将Matlab中的運作結果回傳給C、C++
二、程式實作
我們通過一個簡單的程式demo.c來說明C、C++對Matlab的調用。
#include
#include
#include
#include
#include "engine.h"
int PASCAL WinMain (HANDLE hInstance,
HANDLE hPrevInstance,
LPSTR lpszCmdLine,
int nCmdShow)
{
Engine *ep; // 定義Matlab 引擎
mxArray *a_ptr=NULL;
char buffer[300]; // 定義資料緩沖區
double *wu;
int i,j;
a_ptr=mxCreateDoubleMatrix(10,10,mxREAL);
mxSetName(a_ptr,"wu");
wu=mxGetPr(a_ptr);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
wu[i+10*j]=(j+1)*(j+1)*(i+1)*(i+1);
}
}
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start Matlab engine",
(LPSTR) "demo.c", MB_OK);
exit(-1);
}
engPutArray(ep, a_ptr);
engEvalString(ep,"mesh(wu);");
engEvalString(ep,"print picture.eps -deps;");
engOutputBuffer(ep, buffer, 300);
engClose(ep);
mxDestroyArray(a_ptr);
return(0);
}
當然,該程式在編譯之前還需設定一些環境參數。在不同的開發環境中,其設定方法略有差異,我們以Borland C++ builder開發平台為例加以說明。
1) 首先必須完成Matlab中連結庫的導入工作。在Matlab\extern\include中存在_libmx.def、_libmat.def、_libeng.def等定義檔案,在DOS環境中對它們執行指令:
c:\matlab\extern\include>implib 檔案名.lib 檔案名.def 将獲得_libmx.lib、_libmat.lib、_libeng.lib等新檔案。再将這3個新檔案拷貝到 目錄matlab\extern\
lib中即可。
2)在BCB中建立一工程,在其中加入檔案demo.c
3)打開Project|Option... 對話框,點選Directories/Conditionals。在Include Path 中,加入目錄路徑\extern\include,該路徑包含了engine.h 和matlab .h 等有用的頭檔案。在Library Path 中,加入\bin和\extern\lib 。這兩個目錄路徑包含了外部調用的LIB檔案。
4)點選Project|Add to Project... 對話框,加入如下庫檔案:
_libeng.lib,_libmat.lib 和_libmx.lib。
完成以上配置後,即可編譯運作。程式執行結果如下圖所示。
最後,需要說明的是,使用這種方法調用Matlab 不能脫離Matlab 環境的支撐。另一種方法則是完全脫離Matlab環境,通過動态連接配接庫方式實作對Matlab工具箱函數的調用,這可以通過Mathtools公司的開發平台Mediva來實作。Mediva軟體功能相當強大,提供近千個Matlab的基本功能函數,通過一些必要的設定,就可以直接實作與C、C++的混合程式設計,而不必再依賴Matlab。限于篇幅,在此不作詳細介紹,感興趣的使用者可以通過通路網站www.mathtools.com免費下載下傳試用。