How to build a mex return structure?
現在この質問をフォロー中です
- フォローしているコンテンツ フィードに更新が表示されます。
- コミュニケーション基本設定に応じて電子メールを受け取ることができます。
エラーが発生しました
ページに変更が加えられたため、アクションを完了できません。ページを再度読み込み、更新された状態を確認してください。
古いコメントを表示
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 件のコメント
Jeff
2016 年 6 月 29 日
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
Jeff
2016 年 6 月 29 日
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?
James Tursa
2016 年 6 月 29 日
@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.
Jeff
2016 年 7 月 22 日
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) についてさらに検索
参考
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の 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)
