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

MATLAB 調用 C 程序完全指南:MEX 文件編寫、編譯、調試與性能對比

     編輯:關於C

背景:為什麼要 MEX?

MATLAB 矩陣運算極快,但雙重/多重循環極慢。將熱點循環用 C 實現、編譯為 MEX(動態鏈接庫),可獲數十倍加速,且調用方式與內建函數無異。

一、MEX 源文件結構

  1. 功能子程序:純 C 邏輯,如 double add(double,double)
  2. 入口函數:固定簽名 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])

二、最簡示例:標量加法

// add.c
#include "mex.h"

double add(double x, double y) { return x + y; }

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[]) {
    /* 參數檢查 */
    if (nrhs != 2) mexErrMsgTxt("Two inputs required.");
    if (nlhs > 1)  mexErrMsgTxt("Too many outputs.");

    /* 獲取輸入標量 */
    double a = mxGetScalar(prhs[0]);
    double b = mxGetScalar(prhs[1]);

    /* 創建輸出矩陣 (1x1 double) */
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    double *out = mxGetPr(plhs[0]);

    /* 計算並賦值 */
    *out = add(a, b);
}

編譯與調用

# MATLAB 中
mex add.c          # 生成 add.mexw64 (Windows) / add.mexa64 (Linux)
result = add(1.1, 2.2)  % 直接調用

三、進階示例:Hilbert 矩陣生成(雙重循環加速)

// myhilb.c
#include "mex.h"

void myhilb(double *y, int n) {
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            y[i + j*n] = 1.0 / (i + j + 1);  // 列主序
}

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[]) {
    if (nrhs != 1 || !mxIsDouble(prhs[0]) || mxGetNumberOfElements(prhs[0]) != 1)
        mexErrMsgTxt("Input must be a scalar double.");

    int n = (int)mxGetScalar(prhs[0]);
    plhs[0] = mxCreateDoubleMatrix(n, n, mxREAL);
    myhilb(mxGetPr(plhs[0]), n);
}

四、關鍵 API 速查

五、性能對比:M 文件 vs MEX

% M 文件
tic; m=10000; a=zeros(m,m);
for i=1:m, for j=1:m, a(i,j)=1/(i+j); end; end
toc  % Elapsed time is 3.62 秒

% MEX
tic; b = myhilb(10000); toc  % Elapsed time is 0.73 秒

加速比 ≈ 5x,更複雜邏輯可達 10-100x。

六、Visual Studio 2010/2019/2022 編譯 MEX (64 位)

  1. 新建 DLL 項目(空項目)
  2. 屬性 → C/C++ → 附加包含目錄:$(MATLAB_ROOT)\extern\include
  3. 屬性 → 鏈接器 → 附加庫目錄:$(MATLAB_ROOT)\extern\lib\win64\microsoft
  4. 屬性 → 鏈接器 → 輸入 → 附加依賴項:libmx.lib libmex.lib libmat.lib
  5. 屬性 → 鏈接器 → 輸出文件:$(OutDir)$(TargetName).mexw64
  6. 屬性 → 鏈接器 → 目標計算機:MachineX64
  7. 配置管理器 → 活動解決方案平台 → x64
  8. F7 編譯,輸出 .mexw64

七、VS 中斷點調試 MEX

  1. MATLAB 當前目錄切至 MEX 所在目錄
  2. VS → 調試 → 附加到進程 → 選 MATLAB.exe
  3. C 源碼打斷點
  4. MATLAB 執行 out = myhilb(6)
  5. VS 命中斷點,F10 單步調試

注意:調試期間 MATLAB 假死;調試後需 clear all 卸載 MEX 才能重新編譯。

八、總結

MEX 讓 MATLAB 獲得 C 級性能,核心流程:編寫 mexFunction → mex 編譯 → 直接調用。掌握 mxArray 數據訪問、參數檢查、VS 調試技巧,即可將 MATLAB 原型快速轉化為高性能生產代碼。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
API用途
mxCreateDoubleMatrix(m,n,mxREAL)創建 m×n 雙精度矩陣
mxGetPr(pa)獲取實數數據指針 (double*)
mxGetScalar(pa)獲取 1×1 矩陣的標量值
mxGetM/N(pa)獲取行數/列數
mxIsDouble/IsNumeric/IsComplex類型檢查
mexErrMsgTxt(msg)報錯並返回 MATLAB
mexPrintf(fmt,...)輸出到 MATLAB 命令窗口