首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

Simulink 與 VC++ 6.0 混合編程:MATLAB Engine 接口完整指南

     編輯:VC 教學

架構總覽

VC++ 應用程式 ↔ MATLAB Engine (獨立進程) ↔ Simulink 模型
通訊管道:engine.h 提供的 13 個 C API,核心 6 個:
engOpen/Close、engEvalString、engGet/PutArray、engOutputBuffer。

VC++ 專案配置四步驟

  1. 建立專案:MFC AppWizard / Win32 Console / Win32 Application 均可;
  2. 設定包含目錄:
    $(MATLAB)\extern\include
    $(MATLAB)\extern\include\cpp
  3. 設定庫目錄:
    $(MATLAB)\extern\lib\win32\microsoft (VC6)
  4. 連結庫:libeng.lib libmx.lib libmat.lib(視需求增減)。

Engine 核心 API 速查

函數用途關鍵參數
engOpen(NULL)啟動 MATLAB 進程Win 下 startcmd 必為 NULL
engClose(ep)關閉 Engine成功返回 0
engEvalString(ep, cmd)執行 MATLAB 指令字串任何 Command Window 合法指令
engGetArray(ep, name)從 MATLAB 工作區取變數返回 mxArray*
engPutArray(ep, mxArray*)把變數送入 MATLAB 工作區同名自動覆蓋
engOutputBuffer(ep, buf, len)導向輸出緩衝區捕獲 disp/fprintf 輸出

Simulink 命令列仿真指令

[t, x, y] = sim('modelname')                           // 對話框參數
[t, x, y] = sim('modelname', timespan, options, ut)     // 指定參數
[t, x, y1, y2...] = sim('modelname', timespan, options, ut) // 多輸出

參數詳解:

  • timespan:[]/Tfinal/[Tstart Tfinal]/輸出時間向量;
  • options:simset 產生的結構體,最高優先權覆蓋模型設定;
  • ut:[t, u1, u2...] 輸入矩陣,每欄對應一個 Inport。

VC++ 驅動 Simulink 完整流程

Engine* ep = engOpen(NULL);
if (!ep) { /* 錯誤 */ }

// 1. 載入模型
engEvalString(ep, "modelname");  // 或 open_system('modelname')

// 2. 設定仿真時間 (VC double[] → MATLAB mxArray)
double timespan[2] = { m_fStartTime, m_fStopTime };
mxArray* T = mxCreateDoubleMatrix(1, 2, mxREAL);
memcpy(mxGetPr(T), timespan, 2*sizeof(double));
engPutArray(ep, "T", T);  // 送入工作區變數 T
mxDestroyArray(T);

// 3. 設定 Solver(剛性系統需 ode15s/ode23s 等)
engEvalString(ep, "set_param('modelname', 'Solver', 'ode15s')");

// 4. 執行仿真
engEvalString(ep, "[t, x, y] = sim('modelname', T);");

// 5. 取回結果
mxArray* yArr = engGetArray(ep, "y");
double* yData = mxGetPr(yArr);
int rows = mxGetM(yArr), cols = mxGetN(yArr);
// 複製到 VC 容器...
mxDestroyArray(yArr);

engClose(ep);

關鍵技術難點與對策

1. Solver 選擇與剛性系統

  • 非剛性:ode45(RK45 中階、最常用)、ode23(RK23 低階、快)、ode113(Adams);
  • 剛性:ode15s(NDF 變階)、ode23s(Rosenbrock 2階)、ode23t(梯形)、ode23tb(TR-BDF2);
  • 程式指定 Solver 僅影響當次仿真,模型預設不變;若模型預設非剛性而實際為剛性,仿真會報警但仍按程式指定執行。

2. VC ↔ MATLAB 資料類型轉換

核心模式:mxArray 為橋樑,mxGetPr 取得 double*,配合 memcpy 雙向複製。

// VC → MATLAB
double src[100]; 
mxArray* M = mxCreateDoubleMatrix(10, 10, mxREAL);
memcpy(mxGetPr(M), src, 100*sizeof(double));
engPutArray(ep, "M", M);

// MATLAB → VC
mxArray* M = engGetArray(ep, "M");
double* dst = new double[mxGetNumberOfElements(M)];
memcpy(dst, mxGetPr(M), mxGetNumberOfElements(M)*sizeof(double));
mxDestroyArray(M);

其他類型:mxCreateNumericMatrix 指定 mxINT32_CLASS 等,對應 mxGetData 取 void*。字串用 mxCreateString/mxArrayToString。

3. 常見坑點

  • MATLAB Engine 另起進程,啟動較慢(秒級),適合批次/離線計算,不適合高頻即時控制;
  • engEvalString 同步阻塞,長時間仿真會凍結 UI,需放工作執行緒;
  • 大量資料傳輸開銷大,考慮共享記憶體 / MAT 檔案中轉;
  • 部署機器需安裝完整 MATLAB(非 Runtime),授權成本高。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved