Zdenek Prusa
Zdenek Prusa

Reputation: 181

How to get function calling function from a MEX file

I have a MEX function and I need to get the name of the function which called this MEX function from Matlab. Is there a way how to do it? I have tried

mexCallMatlab(...,"dbstack")

but, it returns an empty result, because it is probably run in the workspace.

Yes, I know I could pass the function name directly as an argument, but that is not an option for me.

Upvotes: 3

Views: 344

Answers (2)

Shanqing Cai
Shanqing Cai

Reputation: 3876

Calling "dbstack" using "mexCallMATLAB" from within the MEX function should do the trick. Just need to be a little careful when converting the output of "dbstack", which is a MATLAB struct, into a string. This is the C MEX code

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, 
  const mxArray *prhs[]) {
    mxArray *mxArr[1];
    mexCallMATLAB(1, mxArr, 0, NULL, "dbstack");

    char *funcName = mxArrayToString(mxGetField(mxArr[0], 0, "name"));

    printf("Function name = %s\n", funcName);
}

This is the MATLAB function calling the MEX function.

function callMyMex()
myMex();
end

When you run the "callMyMex" function, you should see the output:

Function name = callMyMex

Upvotes: 3

chappjc
chappjc

Reputation: 30579

If you run dbstack in the base workspace, the struct will indeed be empty. Here's how I tested it using mexCallMATLAB:

testMEX.cpp

#include "mex.h"

void mexFunction(int nlhs, mxArray *plhs[],  int nrhs, const mxArray *prhs[])
{
    mxArray *dbStruct;
    mexCallMATLAB(1, &dbStruct, 0, NULL, "dbstack");

    plhs[0] = mxDuplicateArray(dbStruct);

    if (mxIsEmpty(dbStruct) || mxGetNumberOfFields(dbStruct) != 3) {
        mexErrMsgTxt("dbstack not available from base workspace");
        return;
    }

    mxArray *callerFileName = mxGetField(dbStruct, 0, "file");
    char *fileStr = mxArrayToString(callerFileName);

    mxArray *callerFunctionName = mxGetField(dbStruct, 0, "name");
    char *funStr = mxArrayToString(callerFunctionName);

    mxArray *callerLineNum = mxGetField(dbStruct, 0, "line");
    int lineNum = static_cast<int>(mxGetScalar(callerLineNum));

    mexPrintf("File: %s\n",fileStr); mxFree(fileStr);
    mexPrintf("Function: %s\n", funStr); mxFree(funStr);
    mexPrintf("Line: %d\n", lineNum);
}

testFun.m

function s = testFun()

s = testMEX;

Output

>> s = testMEX
Error using testMEX
dbstack not available from base workspace 

>> s = testFun
File: testFun.m
Function: testFun
Line: 3

s = 
    file: 'testFun.m'
    name: 'testFun'
    line: 3

Upvotes: 3

Related Questions