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);
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.
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.
I get the following error
In function w_Endline:
/home/prog2/in_out.c:113:19: error: assignment of read-only l ocation ‘*(sent + (sizetype)(endlen * 1ul))’
sent[endlen]='\0';
/home/prog2/in_out.c: In function ‘w_White’:
/home/prog2/in_out.c:119:19: warning: initialization discards ‘const’ qualifier from pointer target type
char* endlen=sent+whitelen;
/home/prog2/in_out.c:120:6: warning: implicit declaration of function ‘isspace’ [-Wimplicit-function-declaration]
while(endlen>sent &&isspace(*endlen))
FILES
1.in_out.c http://ideone.com/nI15F4
void w_Endline(const char* sent)
{
size_t endlen=strlen(sent)-1;
if(sent[endlen]=='\n')
sent[endlen]='\0';
}
void w_White(const char* sent)
{
size_t whitelen=strlen(sent);
char* endlen=sent+whitelen;
while(endlen>sent &&isspace(*endlen))
{
endlen='\0';
--endlen;
}
}
2.in_out.h http://ideone.com/lDxxhY
Dont use const in w_Endline if you are modifying the pointer also you need ctype.h header for isspace() function. Also in w_White function if you are assigning a const pointer the pointer also needs to be const.
char* endlen=sent+whitelen;
should be
const char* endlen=sent+whitelen;// because sent is const
Actually const qualifier means read-only
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
I first store the 3 value into a pair of map like this:
void AddMenuAtlasTexture( int tag, const char* filename, const char* textureName )
{
map<const char*, const char*> _item;
_item.insert(pair<const char*, const char*>(filename, textureName));
m_texturesToLoad.insert(pair<int, map<const char*, const char*> >(tag, _item));
};
then I pass the value to another function like this:
map<const char*, const char*>::iterator _content;
int _tag = (*m_texturesToLoadIterator).first;
_content = (*m_texturesToLoadIterator).second.begin();
AtlasManagerSingleton->AddAtlas((*_content).first, (*_content).second, _tag);
the "textureName" is an absolute path like this kind: "/Users/eddy/Library/Application Support/iPhone Simulator/User/Applications/5FDE0091-2E93-42FE-BB62-05A16429551D/Ranch.app/../Documents/shop_tex.png"
my problem is the first function can get the "textureName" right, but the second function "AddAtlas" can not get the path, the "(*_content).second" is NULL.
and the "AddAtlas" prototype is:
void AtlasManager :: AddAtlas( const char *a_configFile, const char *a_spriteName, int a_nKey )
I develop this in iPhone dev using XCode.
use make_pair instead of pair<int, map<const char*, const char*> >.
use -> instead of *.
the texture loader is a map int -> const char* -> const char*. I don't see where you used the second index.
Probably this:
AtlasManagerSingleton->AddAtlas((*_content).first, (*_content).second, _tag)
Should be:
AtlasManagerSingleton->AddAtlas(_content->first, _content->second.begin()->second, _tag)