Recursively build cell array in MEX? c/c++

Hi, before I even attempt to do this, I wanted to ask if anyone else (including Mathworks staff) has tried to recursively build a cell array? I have to deal with a library (hiredis) that may return nested results in a reply struct. I have to examine the reply type, and if it is a certain type, then I have to traverse all the child replies and examine each of them, etc.
Hiredis sets an arbitrary max nesting level, which I am also going to enforce. I set it to 7, which matches hiredis.
My mind is boggling a bit at what might be involved with recursively adding to the cell array which holds all the results. This is the last major task in writing my redis wrapper and I wish I could just ignore this but there are many redis commands which return replies of a type called "Multi Bulk" which can be arbitrarily nested.
I thought it would be better to ask for help in advance instead of posting a bunch of garbage asking "why I get error".
thx George

답변 (1개)

James Tursa
James Tursa 2013년 3월 7일

1 개 추천

Generally, you can pretty much build and/or examine "nested" cell or struct mxArray variables in the mex environment using the mxSetCell, mxGetCell, mxSetField, mxGetField etc API functions recursively. If you could provide a short descriptive sample (i.e., pseudo-code) of what you are trying to do we can probably advise how to go about it in C/C++.

댓글 수: 3

George Coles
George Coles 2013년 3월 7일
편집: George Coles 2013년 3월 8일
Here is some preliminary code. I am terrible with C, hardly ever do MEX, and am new to Redis, so I am a triple threat.
Edit - here is some code that works to some extent. I am still shaky on memory management and the most elegant way to get data into plhs....
void appendCellArray( mxArray** retVal, int retValRecurseLevel,int recurseMax, redisReply* reply ){
int numChildren;
int elementi;
int replyType;
mwSize dims[2];
if (retValRecurseLevel >= recurseMax){
return;
}
replyType = reply->type;
switch( replyType ){
case REDIS_REPLY_STRING:
{
int index;
unsigned char* output_array_pointer;
int numReplyrows = reply->len;
*retVal = mxCreateNumericMatrix(reply->len, 1, mxUINT8_CLASS, mxREAL);
output_array_pointer = (unsigned char *)mxGetData(*retVal);
for ( index = 0; index < numReplyrows; index++ ) {
output_array_pointer[index] = reply->str[index];
}
}
break;
case REDIS_REPLY_ARRAY:
//cell array to hold results
numChildren = reply->elements;
dims[0] = numChildren;
dims[1] = 1;
*retVal = mxCreateCellArray( 2, &dims[0] );
for( elementi = 0; elementi < numChildren; elementi++ ){
mxArray* childArray;
redisReply* subreply;
subreply = reply->element[elementi];
appendCellArray( &childArray, retValRecurseLevel,recurseMax, subreply );
mxSetCell( *retVal, elementi, childArray );
}
break;
case REDIS_REPLY_INTEGER:
{
*retVal = mxCreateDoubleScalar( reply->integer );
}
break;
case REDIS_REPLY_NIL:
{
const mwSize emptyDims[2] = {0,0};
*retVal = mxCreateNumericArray( 2,emptyDims,mxUINT8_CLASS,mxREAL );
}
break;
case REDIS_REPLY_STATUS:
*retVal = mxCreateString( reply->str );
break;
case REDIS_REPLY_ERROR:
*retVal = mxCreateString( reply->str );
break;
default:
freeReplyObject(reply);
mexErrMsgTxt("we do not know how to deal with this reply type");
}
}
George Coles
George Coles 2013년 3월 18일
no comment on whether I am doing it right?
Jan
Jan 2013년 3월 18일
In general the code looks ok. There are two strong testers on your computer: 1. let the compiler parse the input, 2. let the code run and test the results with your expectations.
Btw., this is not C-code, but C++, because the later allows to declare variables inside the code. But as long as the compiler accept this, this is a cosmethical aspect only.

댓글을 달려면 로그인하십시오.

카테고리

도움말 센터File Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기

제품

질문:

2013년 3월 7일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by