How to build a mex return structure?
이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
이전 댓글 표시
1 개 추천
I am unable to figure out how to build and attach matrices to the structure I have being returned
mwSize dims[2] = {1,NumChans};
plhs[0] = mxCreateStructArray(2, dims, NUMBER_OF_FIELDS, field_names);
I want to place matrices in one of the fields where I'll have a different one for each structure element. I can't seem to find any examples how best to do this, would there possibly be such an example?
Thanks
채택된 답변
You can create an mxArray as you would anywhere else, e.g.
mxArray* myArray = mxCreateDoubleMatrix( 3, 4, mxREAL );
double* dataPtr = mxGetPr( myArray );
// Some code here to fill up myArray however you want using dataPtr
mxSetField( plhs[0], 0, field_names{1}, myArray ); // Assign matrix to first field name of 1st structure in array
mxSetField( plhs[1], 1, field_names{1}, myOtherArray ); // Assign matrix to first field name of 2nd structure in array
etc
with myOtherArray created by whatever method you choose also.
댓글 수: 8
a little more background, I'm using a C++ SDK to read a proprietary data file format, where my mex first extracts the number of channels, then loops through them. The channel read section has a single line function which gets the data for the current channel in the loop, where I'm creating and flushing the buffer used for this each loop, since I don't know how many datapoints there are until the channel information is read.
Here's an abbreviated version of the loop
// read the number of channels
if (ts.getChannelCount(&NumChans))
{
mwSize dims[2] = {1,1};
dims[1] = NumChans;
plhs[0] = mxCreateStructArray(2, dims, NUMBER_OF_FIELDS, field_names);
mxArray *tmp;
for (ChanIndex=0; ChanIndex<NumChans; ChanIndex++)
{
// Get number of data points, x-axis start time and sample rate for this channel
if ( ts.getPointCount(ChanIndex,&NumPoints) && ts.getXBase(ChanIndex, &XBase) && ts.getSampleRate(ChanIndex, &SampleRate) )
{
name_field = mxGetFieldNumber(plhs[0],"NumPoints");
tmp = mxCreateNumericMatrix((mwSize) 1,(mwSize) 1,mxUINT64_CLASS, mxREAL);
*mxGetPr(tmp) = (int long long) NumPoints;
mxSetFieldByNumber(plhs[0],ChanIndex,name_field,tmp);
}
// Read the data for this channel
FTFloat *DataBuf = new FTFloat[NumPoints];
if (ts.getData(ChanIndex, 0, (FTUnsLong)NumPoints, DataBuf))
{
this is where I want to asign the data read into DataBuff
into the plhs[0] structure in the "Data" field
name_field = mxGetFieldNumber(plhs[0],"Data");
mxSetFieldByNumber(plhs[0],ChanIndex,name_field,????);
delete[] DataBuf;
DataBuf = 0;
}
}
}
Well, you should just be able to create another mxArray and then copy your data directly from DataBuf into it as e.g.
mxArray myMatrix = mxCreateNumericArray( 1, NumPoints, mxSINGLE_CLASS, mxREAL );
float *dataPtr = static_cast<float *>( mxGetData( myMatrix ) );
memcpy( dataPtr, DataBuff, 4 * NumPoints );
or something vaguely similar. That code is just modified off the top of my head from code I use somewhere so it may need alterations with casting or other changes.
Jeff
2016년 6월 29일
My problem is understanding how to configure the mx variables. I get a new vector of data each time through the loop, what I can't seem to do is get a variable built that will handle the variable number of channels and points of each channel that aren't known until run time.
It seems I need an array of mxArray pointers so I can fill unique mxArrays for each loop iteration. something like
mxArray *Data = new mxArray[numChans]
but this creates a mex error
Does this make sense?
mxArray *tmp, *Data[1000];
double *dataPtr;
then in the loop
Data[ChanIndex] = mxCreateDoubleMatrix( NumPoints, 1, mxREAL );
dataPtr = mxGetPr( Data[ChanIndex] );
/* Copy data into the mxArray */
for ( index = 0; index < NumPoints; index++ ) {
dataPtr[index] = DataBuf[index];
}
name_field = mxGetFieldNumber(plhs[0],"Data");
mxSetFieldByNumber(plhs[0],ChanIndex,name_field,Data[ChanIndex]);
The Data pointer array is hard coded to be large, is there a better way to do this?
@Jeff: This does not do what you think it does:
tmp = mxCreateNumericMatrix((mwSize) 1,(mwSize) 1,mxUINT64_CLASS, mxREAL);
*mxGetPr(tmp) = (int long long) NumPoints;
You created an mxArray of uint64 class with the first line. Then you try to copy a long long value into that array with the second line. But mxGetPr returns a (double *) type. So the second line converts NumPoints into a double and copies it into the memory location of a uint64. Then when you read this memory location as a uint64 you will get garbage. What you need to do is something like this instead:
long long *longlongptr;
:
tmp = mxCreateNumericMatrix((mwSize) 1,(mwSize) 1,mxUINT64_CLASS, mxREAL);
longlongptr = (long long *) mxGetData(tmp);
*longlongptr = (int long long) NumPoints;
Jeff
2016년 6월 29일
This syntax works, but "new" doesn't seem to work to dynamically allocate mxArray pointers. Is there a way to do it?
James Tursa
2016년 6월 29일
편집: James Tursa
2016년 6월 29일
Can you post your current code or pseudo-code with comments as to what you want at the end of the process? I.e., "I want an X-element structure with fields named AAA, BBB, etc and each field will contain ETC ETC".
I am not really sure where you are getting stuck. Once you know how many elements you want (NumChans?), you loop through them to set the field values. Looks like you are doing that already, so I don't see where you are having problems with this.
I neglected to make it an array of pointers, this works fine
mxArray **Data = new mxArray*[ NumChans ];
추가 답변 (0개)
카테고리
도움말 센터 및 File Exchange에서 Write C Functions Callable from MATLAB (MEX Files)에 대해 자세히 알아보기
참고 항목
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
