Matlab调用C程序

有时需要用Matlab调试某些C语言开发的函数库,需要在Matlab里面查看执行效果。

整个的参考例子如下:

#include <mex.h>

// Check if some command is really some givent one
static bool commandIs(const mxArray* mxCommand, const char* command)
{
    double result;
    mxArray* plhs1[1];
    mxArray* prhs1[1];
    mxArray* plhs2[1];  
    mxArray* prhs2[2];

    if (mxCommand == NULL) { mexErrMsgTxt("'mxCommand' is null"); return false; }
    if (command == NULL) { mexErrMsgTxt("'command' is null"); return false; }
    if (!mxIsChar(mxCommand)) { mexErrMsgTxt("'mxCommand' is not a string"); return false; }

    // First trim
    prhs1[0] = (mxArray*)mxCommand;
    mexCallMATLAB(1, plhs1, 1, prhs1, "strtrim");

    // Then compare
    prhs2[0] = mxCreateString(command);
    prhs2[1] = plhs1[0];
    mexCallMATLAB(1, plhs2, 2, prhs2, "strcmpi");

    // Return comparison result
    result = mxGetScalar(plhs2[0]);  
    return (result != 0.0);
}

static void processHelpMessageCommand(void)
{
    mexPrintf("DspMgr('init') init return Handle,return nil if failed. use 'release' free memory\n"); 
    mexPrintf("DspMgr('release',handle) free memory\n");     
}

static void processInitCommand(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{        
    char* example_buffer = malloc(512);
    plhs[0] = mxCreateNumericMatrix(1,1,mxUINT64_CLASS,mxREAL);
    long long *ip = (long long *) mxGetData(plhs[0]);
    *ip = (long long)example_buffer;
}

static void processReleaseCommand(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    if(nrhs != 2) {
        mexErrMsgTxt("release need 1 params"); 
    } else {
        if(!mxIsUint64(prhs[1])) {
           mexErrMsgTxt("release handle must be UINT64 format");
           return;
        }
        
        int M=mxGetM(prhs[1]); //获得矩阵的行数 
        int N=mxGetN(prhs[1]);  //获得矩阵的列数 
        if((1 != M) &&(1 != N)) {
           mexErrMsgTxt("release handle must be 1*1 array format");
           return; 
        }
        
        long long ip = mxGetScalar(prhs[1]);
        char* example_buffer = (char*)ip;
        free(example_buffer);
        
        //return true avoid warnning
        plhs[0] = mxCreateNumericMatrix(1,1,mxINT8_CLASS,mxREAL);
        char* mx_data = (char *) mxGetData(plhs[0]);
        mx_data[0] = 1;
    }    
}

// Mex entry point
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    // Arguments parsing
    if (nrhs < 1) { mexErrMsgTxt("Not enough input arguments. use 'DspMgr help' for help message."); return; }
    if (!mxIsChar(prhs[0])) { mexErrMsgTxt("First parameter must be a string."); return; }

    // Command selection
    if (commandIs(prhs[0], "HELP")) { processHelpMessageCommand(); }
    else if (commandIs(prhs[0], "init")) { processInitCommand(nlhs, plhs, nrhs, prhs); }
    else if (commandIs(prhs[0], "release")) { processReleaseCommand(nlhs, plhs, nrhs, prhs); }
    else { mexErrMsgTxt("Unknown command or command not implemented yet."); }
}

尤其注意上面例子里我们如何隐藏一个C里申请的指针并传递给Matlab

Matlab的调用例子如下:

mex -output DspMgr 'CFLAGS="\$CFLAGS -std=c99"' '*.c'

v = DspMgr('init')

DspMgr('release',v)

参考链接


发布者

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注