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.
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
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
Related
I would like to pass a String vector into an external C function.
In a minimal example I just want to pass the String vectors (or 1D array) through the C function.
My Modelica function looks like:
function testreadstri
input String instri[2];
output String outstri[2];
external "C" test_stri(instri,, size(instri, 1), outstri);
annotation (Include="#include <ebcmysql.cpp>", Library="libmysql");
end testreadstri;
My C fucntion looks like:
void test_stri(const char* thestring, size_t nLines, const char **testresult)
{
//bout = 12.3;
size_t iLines;
//size_t nLines;
iLines = 0;
//nLines = 1;
while ( iLines <= nLines ) {
<LINE_OF_INTEREST>
iLines++;
}
}
I tried for <LINE_OF_INTEREST> the following lines:
testresult[iLines] = thestring[iLines];
strcpy(testresult[iLines], thestring[iLines]);
What works, but of course does not pass the input through as an output, is:
testresult[iLines] = "aTestString";
Is there any possibility to handle Modelica input String vectors in the external C function?
Thanks in advance!
Here's a short, self-contained and compilable example demonstrating both input string and output string handling of a pure external function in Modelica
model Model
function testreadstri
input String instri[2];
output String outstri[2];
external "C" test_stri(instri, size(instri, 1), outstri, size(outstri, 1));
annotation(Include="
#include \"ModelicaUtilities.h\"
#include <stdlib.h>
#include <string.h>
void test_stri(const char** thestring, size_t nLinesIn, const char** testresult, size_t nLinesOut)
{
size_t iLines;
// example for input string handling
for (iLines = 0; iLines < nLinesIn; iLines++) {
ModelicaFormatMessage(\"%s\\n\", thestring[iLines]);
}
// example for output string handling
for (iLines = 0; iLines < nLinesOut; iLines++) {
char* line = ModelicaAllocateStringWithErrorReturn(6);
if (line != NULL) {
strcpy(line, \"result\");
testresult[iLines] = line;
}
}
}");
end testreadstri;
String s[:] = testreadstri({"first", "second"});
end Model;
Yes, this is supported by the Modelica specification, see https://specification.modelica.org/v3.4/Ch12.html#argument-type-mapping.
Is it possible to get the variable name of a mxArray pointer?
const char * strFileMatFile = "path/to/mat/file.mat";
pMatFile = matOpen(strFile, "r");
const char * strVarName = "a" // name of a variable inside the mat file
// which I want to find with the mxArray pointer
// Get a pointer to the variable with name strVarName in the mat file
mxArray *pVariable = matGetVariable(pMatFile, strVarName);
const char * strVarNameFromPtr = mxArrayToString(pVariable);
mxArrayToString(pVariable) returns null. Is there a function that can return the variable name of a mxArray pointer?
Something like:
const char * strVarNameFromPtr = mxGetName(pVariable);
I wrote a mexfunction on c++ code, then compiled it to get mexa64 file. After I used mexa64 file for many times, my PC memory run out.
Here is my mexfunction:
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
// double *res ;// the final result index
int status1,status2,status3;
double *res ;
double *out_mat;
double *x_idx,*y_idx,*width_idx,*height_idx;
char* sequence_path;// the tracking image sequences
char* sequence_name;// the tracking image sequences
char* output_path;// save the output
int start_frame=(int)mxGetScalar(prhs[0]);
int end_frame=(int)mxGetScalar(prhs[1]);
int Max_track_number=(int)mxGetScalar(prhs[2]);
/* Extract the inputs */
int buflen1=(mxGetM(prhs[3])*mxGetN(prhs[3]))+1;
sequence_path= (char *)mxCalloc(buflen1,sizeof(char));
status1=mxGetString(prhs[3],sequence_path,buflen1);
int buflen2=(mxGetM(prhs[4])*mxGetN(prhs[4]))+1;
sequence_name= (char *)mxCalloc(buflen2,sizeof(char));
status2=mxGetString(prhs[4],sequence_name,buflen2);
int buflen3=(mxGetM(prhs[5])*mxGetN(prhs[5]))+1;
output_path= (char *)mxCalloc(buflen3,sizeof(char));
status3=mxGetString(prhs[5],output_path,buflen3);
if(status3!=0)
mexWarnMsgTxt("Not enough space. String is truncated.");
float x=(float)mxGetScalar(prhs[6]);
float y=(float)mxGetScalar(prhs[7]);
float width=(float)mxGetScalar(prhs[8]);
float height=(float)mxGetScalar(prhs[9]);
x_idx=mxGetPr(prhs[6]);
y_idx=mxGetPr(prhs[7]);
width_idx=mxGetPr(prhs[8]);
height_idx=mxGetPr(prhs[9]);
mexPrintf("the dimension is %f,%f,%f,%f\n",*x_idx,*y_idx,*width_idx,*height_idx);
int N1=mxGetM(prhs[6])*mxGetN(prhs[6]);
int N2=mxGetM(prhs[7])*mxGetN(prhs[7]);
int N3=mxGetM(prhs[8])*mxGetN(prhs[8]);
int N4=mxGetM(prhs[9])*mxGetN(prhs[9]);
if(N1!=N2|N2!=N3|N3!=N4)
mexErrMsgTxt("the dimension of the initial bounding box parameter is wrong");
int NN=N1;
plhs[0] = mxCreateDoubleMatrix(Max_track_number*5*NN,1,mxREAL);
out_mat = mxGetPr(plhs[0]);
plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
res = mxGetPr(plhs[1]);
*res=struck_track(start_frame,end_frame,Max_track_number,sequence_path,sequence_name,output_path,out_mat,x_idx,y_idx,width_idx,height_idx,NN);
}
Is there some problems that may cause the exhaustion of memory?
you should use mxFree whenever using the following:
mxCalloc
mxMalloc
mxRealloc
mxArrayToString
I can see from your code that you are using mxCalloc but there is no corresponding mxFree for the same.
Besides using mxFree you can also increase the Java Heap Size. You can find it under settings, general, java heap memory.
Trying to use perl API functions in C program. Couldn't find the function to do regular expression match. Wish there is a function like regexmatch in the following program.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* str = newSVpv(argv[1], strlen(argv[1]));
if (regexmatch(str, "/hi (\S+)/")) {
printf("found a match\n");
}
return 0;
}
I know it's possible to use pcre library, just wonder if it's possible to get it from perl library here (libperl.so.5.14.2 on ubuntu 12.04)
Thanks!
UPDATE 1:
Did some google search and got the following simple program compiling. But when I ran the program as ./a.out ping pin, it gave "Segmentation fault" in the "pregcomp" function. Not sure why.
#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include <sys/time.h>
#include <embed.h>
typedef unsigned long ulong;
static PerlInterpreter *my_perl; /*** The Perl interpreter ***/
struct REGEXP * const engine;
int main(int argc, char **argv, char **env) {
int numOfArgs = 0;
PERL_SYS_INIT3(&numOfArgs, NULL, NULL);
my_perl = perl_alloc();
perl_construct(my_perl);
SV* reStr = newSVpv(argv[2], strlen(argv[2]));
printf("compiling regexp\n");
REGEXP * const compiled_regex = pregcomp(reStr, 0);
printf("execing regexp\n");
int len = strlen(argv[1]);
pregexec(compiled_regex, argv[1], argv[1] + len, argv[1], 5, NULL, 0);
return 0;
}
Don't mess with Perl's private internals. Call a Perl sub that uses the match operator.
Say you previously compiled the following in your interpreter (using eval_pv),
sub regex_match { $_[0] =~ $_[1] }
Then you can call
static bool regex_match_sv(SV* str, SV* re) {
dSP;
bool matched;
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(str);
XPUSHs(re);
PUTBACK;
call_pv("regex_match", G_SCALAR);
SPAGAIN;
matched = SvTRUE(POPs);
PUTBACK;
FREETMPS;
LEAVE;
return matched;
}
I'm trying to access MATLAB through Engine with MetaTrader Terminal 4( a trading software from MetaQuotes metatrader4 )
I use a DLL file to communicate between MetaTrader and MATLAB.
In the code, if I put this code in a single function, it works.
But if I separate it into two distinct functions, it runs forever/bugs out
#include "stdafx.h"
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
#include <windows.h>
#include <memory.h>
#include "engine.h"
using namespace std;
#define MT4_EXPFUNC __declspec(dllexport)
Engine *pEng = NULL;
mxArray *closev = NULL;
double *closevp = NULL;
mxArray *getPArray = NULL;
MT4_EXPFUNC void InitEngine( int dummy )
{
pEng = engOpen( NULL );
}
MT4_EXPFUNC void InitCloseBuffer( int size )
{
closev = mxCreateDoubleMatrix( 1, size, mxREAL );
if ( closev != NULL )
closevp = mxGetPr( closev );
// ------------------------------------------------------------------
// the following code bugs when separated from the code above
// and put in another function called right after this one
engPutVariable( pEng, "closev", closev );
engEvalString( pEng, "[mainNet] = PTrainInit();" );
engEvalString( pEng, "[hitrate, mainNet] = PTrain(mainNet, closev);" );
engEvalString( pEng, "outGetP = PGetPrediction(mainNet, closev)" );
getPArray = engGetVariable( pEng, "outGetP" );
double *p;
if ( getPArray != NULL )
p = mxGetPr( getPArray );
// end of the separated code
// -----------------------------------------------------------------
}
I need to separate both functions though,because I need to fill closev with values.
What am I doing wrong?
thanks
Jeff
ok, I found the answer: initially I had made a standalone MATLAB Project, that was working fine but closev was column-wise and in the DLL closev is row-wise.
Also, populating closev and then using the second, separated, function was a totally different use of the function insides than with closev not populated.
These two things made it look strange error-wise though.
Glad I could make it work.
JfLB