Hi I have the following structure in C++. I am reading a
file and at the end of each loop I want to pass my structure
to MATLAB with mex fucntion. Any help please ?
On Thu, 1 Nov 2007 00:26:33 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Hi I have the following structure in C++. I am reading a
>file and at the end of each loop I want to pass my structure
>to MATLAB with mex fucntion. Any help please ?
>
>struct Frame
>{
> double frame_no;
> double dist[3072];
> double ampl[3072];
>};
>
>struct UShortFrame
>{
> unsigned frame_no;
> unsigned short dist[3072];
> unsigned short ampl[3072];
>
>};
>
>void ReadFromFile(const char *filename, int ArraySize)
>{
>
> int i;unsigned read_frame_no;
> UShortFrame* usframe = new UShortFrame;
>
> ifstream filein(filename, ios::in | ios::binary);
> if(!filein) {
> std::cout << "Cannot open file to read.\n"; }
> if (filein.read((char*)usframe,
>sizeof(UShortFrame)))
> {
> Frame* frame = new Frame;
> frame->frame_no = usframe->frame_no;
> for (int i = 0; i < 3072; ++i)
> {
> frame->dist[i] = usframe->dist[i];
> frame->ampl[i] = usframe->ampl[i];
>
> }
>
> }
> filein.close();
> delete []usframe;
> // cout<<(*frame).dist[0]<<endl;
> // pass frame structure to MATLAB
>
> }
Here is a complete working mex file that puts Frame and UShortFrame
structures into the MATLAB base workspace. mPut1 and mPut2 could
possibly be optimized a bit, but you get the idea. There are a few
points to note about this mex file:
1) I knew for this example that the ARRAYSIZE was 3072, so I didn't
bother to check that sizeof(double)*ARRAYSIZE and sizeof(unsigned
short)*ARRAYSIZE did not overflow a size_t. For more robust code one
would check this result before using it.
2) I didn't bother to check the return values from
mxCreateStructMatrix and mxCreateNumericMatrix to see that they
completed ok because this was a mex file. For mex files, if they don't
complete ok then they will not return at all ... MATLAB will simply
clean up allocated memory it knows about and exit and return control
back to MATLAB. If you use this code in an engine application then you
*will* have to put in code to check for valid return values.
3) I used the mxCalloc function to create new structure variables
instead of using the C++ "new" operator for two reasons. First, this
lets people use this example using the built-in lcc compiler in case
they don't have a supported C++ compiler. Second, (and I am not at all
sure about this one), I don't think the MATLAB memory manager knows
anything about any memory you allocated with the "new" operator. So if
anything goes wrong with any of the mxCreate... or mxCalloc routines
and the mex file exits back to MATLAB, all of the memory associated
with any mxCreate... or mxCalloc calls will get freed, but your
allocated variables created with the "new" operator may not get
deleted. This would be a potential source for a memory leak. (Can
anyone out there in the MATLAB community who knows more about this
confirm what happens in this case? I need help here.)
4) Creating the structure variables using mxCalloc was relative simple
in this case because the structure was straightforward. The example
would be more complex if your structure had pointers that pointed to
other allocated memory, etc. And freeing this memory with mxFree for
these cases would also be more complex ... would need to free the low
levels first, etc. After having said this, I will point out that the
MATLAB memory manager will save you and free all memory you allocated
with the mxCreate... and mxCalloc calls when the mex file exits, even
if you forget to do it.
Hi James,
Thanks for putting so much effort in for the reply. However,
you seems to have made all the processing within the
mexFunction. On the otherhand I want it to be used as
wrapper function. I want to do the implementation in my C++
function and have mexFunction return it. I have posted my
code, can you please correct me how to pass the values that
my function is reading.
Thanks,
Hi James,
Thanks for putting so much effort in for the reply. However,
you seems to have made all the processing within the
mexFunction. On the otherhand I want it to be used as
wrapper function. I want to do the implementation in my C++
function and have mexFunction return it. I have posted my
code, can you please correct me how to pass the values that
my function is reading.
Thanks,
On Fri, 2 Nov 2007 06:12:01 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Hi James,
>Thanks for putting so much effort in for the reply. However,
>you seems to have made all the processing within the
>mexFunction. On the otherhand I want it to be used as
>wrapper function. I want to do the implementation in my C++
>function and have mexFunction return it.
Before I write any more code, I need to clearly understand what it is
you are after. I gave you C routines that put your structures into the
MATLAB workspace using any name you like (I used "f" and "u" but you
could change that). You can call these routines from anywhere in your
code to put any number of your variables into the MATLAB workspace.
Apparently this is not what you want, exactly, so I need some help in
understand what you want. Could you write a hypothetical MATLAB
command line and then describe what it is you expect to happen? For
example, if you named my original file structput.c, then it would be
used as follows:
>> mex structput.c
>> structput
and the result would be two structure variables, f and u, that are in
the MATLAB workspace.
Are you trying to pass arguments, like this?
>> [out1 out2] = structmex(in1, in2, in2)
Do you get what I am asking? Please give me an example of a command
line as you would like it to work and describe what should happen when
you invoke it. Thanks.
Hi James
I do like to pass on arguments like [a,b]=strucmex(in1,in2);
I have modified you mex function and I have been able to
pass input arguments but yet to succeed with output
arguments. Your example is no doubt an excellent reply. But
as this is an initial block and I need to know if I have my
somefun, how will I be able to pass argument input and
output argumnets as shown in MEX help in matlab along with
structure passing that you have shown.
On Sat, 3 Nov 2007 02:48:34 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Hi James
>I do like to pass on arguments like [a,b]=strucmex(in1,in2);
>I have modified you mex function and I have been able to
>pass input arguments but yet to succeed with output
>arguments. Your example is no doubt an excellent reply. But
>as this is an initial block and I need to know if I have my
>somefun, how will I be able to pass argument input and
>output argumnets as shown in MEX help in matlab along with
>structure passing that you have shown.
>
>void mexFunction(int nlhs, mxArray *plhs[], int nrhs,
> const mxArray *prhs[])
>{
> struct Frame *f;
> struct UShortFrame *u;
> size_t t1 = 1;
> int i,mrows, ncols;;
> double *f_count;
> char *filename;
>
> mrows = mxGetM(prhs[0]);
> ncols = mxGetN(prhs[0]);
> f_count = mxGetPr(prhs[0]);
> filename=mxArrayToString(prhs[1]);
>
>
> ifstream filein(filename, ios::in | ios::binary);
>
> if(!filein) {
> std::cout << "Cannot open file to read.\n"; }
>
> u = (struct UShortFrame *) mxCalloc( t1, sizeof(struct
>UShortFrame) );
> f = (struct Frame *) mxCalloc( t1, sizeof(struct Frame) );
>
> (filein.read((char*)u,sizeof(UShortFrame)));
>
> {
> f->frame_no = u->frame_no;
> for (int i = 0; i < ARRAYSIZE; ++i)
> {
> f->dist[i]=u->dist[i];
> f->ampl[i]=u->ampl[i];
>
> }
> }
>
> if( mPut1(f, "f") )
> mexPrintf("mPut1 for f did not work\n");
>
> if( mPut2(u, "u") )
> mexPrintf("mPut2 for u did not work\n");
> filein.close();
> mxFree(f);
> mxFree(u);
>
>}
So if you want to invoke it as follows:
[a,b]=strucmex(in1,in2);
then do you want f to be put into the first output argument a, and u
to be put in the second arbument b? I can easily modify my code to do
this if that is what you really want.
On Sat, 3 Nov 2007 12:50:35 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Yes, like that.
>Thanks
Try this. I couldn't test it because I don't have your file. One note,
however, is that you don't use the first input argument for anything
so I don't know why you are passing it in, but I left the code there
because you wrote it that way.
if( nrhs != 2 )
mexErrMsgTxt("Must have exactly two input arguments\n");
if( nlhs > 2 )
mexErrMsgTxt("Must have <= two output arguments\n");
if( !mxIsDouble(prhs[0]) )
mexErrMsgTxt("1st input argument must be double\n");
if( !mxIsChar(prhs[1]) )
mexErrMsgTxt("2nd input argument must be char\n");
// Why are you doing this? You don't use mrows, ncols, or f_count
anywhere
mrows = mxGetM(prhs[0]);
ncols = mxGetN(prhs[0]);
f_count = mxGetPr(prhs[0]);
filename = mxArrayToString(prhs[1]);
ifstream filein(filename, ios::in | ios::binary);
if(!filein) {
std::cout << "Cannot open file to read.\n"; }
u = (struct UShortFrame *) mxCalloc( t1, sizeof(struct UShortFrame)
);
f = (struct Frame *) mxCalloc( t1, sizeof(struct Frame) );
Hi James, one last thing if you can show me to pass to
MATLAB these two structure values ( dist and ampl) as two
output arguments and not as structures. ?
Thanks,
On Sun, 4 Nov 2007 09:22:27 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Hi James, one last thing if you can show me to pass to
>MATLAB these two structure values ( dist and ampl) as two
>output arguments and not as structures. ?
>Thanks,
1) Do you want to pass f.dist and f.ampl and u.dist and u.ampl? i.e.,
do you want to pass all of them? Or just one of the versions, either
the double or the short?
2) Do you want to pass them in addition to the structures that are
already passed, or in place of the structures that are already passed?
Note that once the structures are in the MATLAB workspace, you can get
at the individual arrays easily. For example, using the current code I
just supplied:
>> [a b] = structput(1.0,'myfile');
then you can get at the individual arrays by typing a.dist, a.ampl,
b.dist, and b.ampl in the MATLAB workspace. For example:
>> sum(a.dist)
Finally, note that I have assumed that an unsigned short in C was a
16-bit quantity. This isn't strictly guaranteed in C. You are really
only guaranteed that a short is at least 16 bits, but it could be
longer. To be more robust one would check sizeof(short) and then use
an mxUINT16_CLASS or an mxUINT32_CLASS accordingly.
Hi
> 1) Do you want to pass f.dist and f.ampl and u.dist and
>u.ampl? i.e.,do you want to pass all of them? Or just one
>of the versions, either> the double or the short?
Only f.ampl and f.dist.
> 2) Do you want to pass them in addition to the structures
>that are already passed, or in place of the structures that
>are already passed?
No only them, not the structure
>Note that once the structures are in the MATLAB workspace,
>you can get at the individual arrays easily. For example,
>using the current code I
> just supplied:
I know that I can access the structured variables, but my
code works better in a non structured way as I have to do
some manipulation like 'find' which does not work on cells
so I again have to put loops in Matlab which will slow down
my processing time.
> Finally, note that I have assumed that an unsigned short
>in C was a 16-bit quantity. This isn't strictly guaranteed
>in C. You are really only guaranteed that a short is at
>least 16 bits, but it could be longer. To be more robust
>one would check sizeof(short) and then use
> an mxUINT16_CLASS or an mxUINT32_CLASS accordingly.
On Mon, 5 Nov 2007 00:03:11 +0000 (UTC), "Faisal "
<faisal_mufti.nospam@yahoo.com> wrote:
>Hi
>> 1) Do you want to pass f.dist and f.ampl and u.dist and
>>u.ampl? i.e.,do you want to pass all of them? Or just one
>>of the versions, either> the double or the short?
>
>Only f.ampl and f.dist.
>
>> 2) Do you want to pass them in addition to the structures
>>that are already passed, or in place of the structures that
>>are already passed?
>
>No only them, not the structure
>
>>Note that once the structures are in the MATLAB workspace,
>>you can get at the individual arrays easily. For example,
>>using the current code I
>> just supplied:
>
>I know that I can access the structured variables, but my
>code works better in a non structured way as I have to do
>some manipulation like 'find' which does not work on cells
>so I again have to put loops in Matlab which will slow down
>my processing time.
>
>> Finally, note that I have assumed that an unsigned short
>>in C was a 16-bit quantity. This isn't strictly guaranteed
>>in C. You are really only guaranteed that a short is at
>>least 16 bits, but it could be longer. To be more robust
>>one would check sizeof(short) and then use
>> an mxUINT16_CLASS or an mxUINT32_CLASS accordingly.
>
>Thanks, I will see to it.
>
>Regards,
>Faisal
Here it is. I deleted the first double argument which you were not
using. There is only one input argument, the filename. The double
versions of dist and ampl are the two output arguments.
if( nrhs != 1 )
mexErrMsgTxt("Must have exactly one input argument\n");
if( nlhs > 2 )
mexErrMsgTxt("Must have <= two output arguments\n");
if( !mxIsChar(prhs[0]) )
mexErrMsgTxt("Input argument must be char\n");
Public Submission Policy
NOTICE: Any content you submit to MATLAB Central, including personal information, is not subject to the protections which may be afforded information collected under other sections of The MathWorks, Inc. Web site. You are entirely responsible for
all content that you upload, post, e-mail, transmit or otherwise make available via MATLAB Central. The MathWorks does not control the content posted by visitors to MATLAB Central and, does not guarantee the accuracy, integrity, or quality of such content.
Under no circumstances will The MathWorks be liable in any way for any content not authored by The MathWorks, or any loss or damage of any kind incurred as a result of the use of any content posted, e-mailed, transmitted or otherwise made available
via MATLAB Central. Read the complete Disclaimer prior to use.