VC++ 應用程式 ↔ MATLAB Engine (獨立進程) ↔ Simulink 模型
通訊管道:engine.h 提供的 13 個 C API,核心 6 個:
engOpen/Close、engEvalString、engGet/PutArray、engOutputBuffer。
$(MATLAB)\extern\include$(MATLAB)\extern\include\cpp$(MATLAB)\extern\lib\win32\microsoft (VC6)libeng.lib libmx.lib libmat.lib(視需求增減)。| 函數 | 用途 | 關鍵參數 |
|---|---|---|
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 輸出 |
[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。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);
ode45(RK45 中階、最常用)、ode23(RK23 低階、快)、ode113(Adams);ode15s(NDF 變階)、ode23s(Rosenbrock 2階)、ode23t(梯形)、ode23tb(TR-BDF2);核心模式: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。
engEvalString 同步阻塞,長時間仿真會凍結 UI,需放工作執行緒;