Thread Subject: mex file wrapper for dll needing function handle

Subject: mex file wrapper for dll needing function handle

From: Todd Welti

Date: 3 Mar, 2009 07:41:02

Message: 1 of 10


I'm trying to implement this idea from tech note 1-6C8PEQ, where a mex file wrapper is used to get around the limitation in matlab that you can't pass a function handle to a loaded dll library (which would be used as a callback). In my case the dll would return three doubles, x, y, and z into "mycallback", which I woule like to return to Matlab ("myMatCallback"). It would look like shown below. I cant for the life of me figure out how to get x,y and z into the format of prhs for hte mexCallMatlab command. Any suggetions appreciated. I can compile the code in general, except for anything that I have tried to get pointers to x,y, and z and make the prhs array, generates errors like: 'cannot convert parameter 1 from 'double' to 'const mxArray *'

#include "mex.h"
#include "myAPI.h"

// Callback function
void myCallback(double x, double y, double z)
{


/* THIS IS THE PART THAT HAS ME STUMPED*/


mexCallMATLAB(0, NULL, 1, prhs,"myMatCallback");
}

// MEX Gateway
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

void (*cbPtr)(double x, double y, double z) = NULL;
cbPtr = myCallback;

// Assume that myAPIRoutine is implemented in myAPI.dll
myAPIRoutine(cbPtr);
}

 

Subject: mex file wrapper for dll needing function handle

From: Ashish Uthama

Date: 3 Mar, 2009 20:48:33

Message: 2 of 10

On Tue, 03 Mar 2009 02:41:02 -0500, Todd Welti <twelti@harman.com> wrote:

>
> I'm trying to implement this idea from tech note 1-6C8PEQ, where a mex
> file wrapper is used to get around the limitation in matlab that you
> can't pass a function handle to a loaded dll library (which would be
> used as a callback). In my case the dll would return three doubles, x,
> y, and z into "mycallback", which I woule like to return to Matlab
> ("myMatCallback"). It would look like shown below. I cant for the life
> of me figure out how to get x,y and z into the format of prhs for hte
> mexCallMatlab command. Any suggetions appreciated. I can compile the
> code in general, except for anything that I have tried to get pointers
> to x,y, and z and make the prhs array, generates errors like: 'cannot
> convert parameter 1 from 'double' to 'const mxArray *'
>
> #include "mex.h"
> #include "myAPI.h"
>
> // Callback function
> void myCallback(double x, double y, double z)
> {
>
>
> /* THIS IS THE PART THAT HAS ME STUMPED*/
>
>
> mexCallMATLAB(0, NULL, 1, prhs,"myMatCallback");
> }
>
> // MEX Gateway
> void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
> *prhs[])
> {
>
> void (*cbPtr)(double x, double y, double z) = NULL;
> cbPtr = myCallback;
>
> // Assume that myAPIRoutine is implemented in myAPI.dll
> myAPIRoutine(cbPtr);
> }
>
>

mxCreateScalar will help you convert a double to a mxArray.

//air code!
mxArray* prhs[3];
mwSize dims[2]={ 1 1};
prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
mexGetPr(prhs[0])=x;
//..so on for y and z




Subject: mex file wrapper for dll needing function handle

From: James Tursa

Date: 3 Mar, 2009 21:19:03

Message: 3 of 10

"Ashish Uthama" <first.last@mathworks.com> wrote in message <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
>
> mxCreateScalar will help you convert a double to a mxArray.
>
> //air code!
> mxArray* prhs[3];
> mwSize dims[2]={ 1 1};
> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
> mexGetPr(prhs[0])=x;
> //..so on for y and z
>

Couple of typos. Since dims is an array, it will act as a double * when passed, so you don't need the &dims in the call, just dims. And you are missing a comma in the dims initialization. Also, mxGetPr returns a pointer result that is not an lvalue. You need to dereference it for the assignment. e.g.

 mxArray* prhs[3];
 mwSize dims[2]={ 1, 1};
 prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
 *(mexGetPr(prhs[0])) = x;

Or, as you almost pointed out, you can use mxCreateDoubleScalar for this:

prhs[0] = mxCreateDoubleScalar(x);

James Tursa

Subject: mex file wrapper for dll needing function handle

From: James Tursa

Date: 3 Mar, 2009 21:25:05

Message: 4 of 10

"James Tursa" <aclassyguywithaknotac@hotmail.com> wrote in message <gok6s7$6oc$1@fred.mathworks.com>...
>
> ... Since dims is an array, it will act as a double * when passed ...

mwSize *

James Tursa

Subject: mex file wrapper for dll needing function handle

From: Todd Welti

Date: 3 Mar, 2009 21:36:01

Message: 5 of 10

"Ashish Uthama" <first.last@mathworks.com> wrote in message <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
> On Tue, 03 Mar 2009 02:41:02 -0500, Todd Welti <twelti@harman.com> wrote:
>
> >
> > I'm trying to implement this idea from tech note 1-6C8PEQ, where a mex
> > file wrapper is used to get around the limitation in matlab that you
> > can't pass a function handle to a loaded dll library (which would be
> > used as a callback). In my case the dll would return three doubles, x,
> > y, and z into "mycallback", which I woule like to return to Matlab
> > ("myMatCallback"). It would look like shown below. I cant for the life
> > of me figure out how to get x,y and z into the format of prhs for hte
> > mexCallMatlab command. Any suggetions appreciated. I can compile the
> > code in general, except for anything that I have tried to get pointers
> > to x,y, and z and make the prhs array, generates errors like: 'cannot
> > convert parameter 1 from 'double' to 'const mxArray *'
> >
> > #include "mex.h"
> > #include "myAPI.h"
> >
> > // Callback function
> > void myCallback(double x, double y, double z)
> > {
> >
> >
> > /* THIS IS THE PART THAT HAS ME STUMPED*/
> >
> >
> > mexCallMATLAB(0, NULL, 1, prhs,"myMatCallback");
> > }
> >
> > // MEX Gateway
> > void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray
> > *prhs[])
> > {
> >
> > void (*cbPtr)(double x, double y, double z) = NULL;
> > cbPtr = myCallback;
> >
> > // Assume that myAPIRoutine is implemented in myAPI.dll
> > myAPIRoutine(cbPtr);
> > }
> >
> >
>
Thanks, but should i use
> mxCreateScalar will help you convert a double to a mxArray.
>
> //air code!
> mxArray* prhs[3];
> mwSize dims[2]={ 1 1};
> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
> mexGetPr(prhs[0])=x;
> //..so on for y and z
>
>
>
>
Thanks, but should i use mxCreateScalar or mcCreateNumericArray?

Subject: mex file wrapper for dll needing function handle

From: Ashish Uthama

Date: 3 Mar, 2009 21:49:07

Message: 6 of 10

On Tue, 03 Mar 2009 16:19:03 -0500, James Tursa
<aclassyguywithaknotac@hotmail.com> wrote:

> "Ashish Uthama" <first.last@mathworks.com> wrote in message
> <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
>>
>> mxCreateScalar will help you convert a double to a mxArray.
>>
>> //air code!
>> mxArray* prhs[3];
>> mwSize dims[2]={ 1 1};
>> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
>> mexGetPr(prhs[0])=x;
>> //..so on for y and z
>>
>
> Couple of typos. Since dims is an array, it will act as a double * when
> passed, so you don't need the &dims in the call, just dims. And you are
> missing a comma in the dims initialization. Also, mxGetPr returns a
> pointer result that is not an lvalue. You need to dereference it for the
> assignment. e.g.
>
> mxArray* prhs[3];
> mwSize dims[2]={ 1, 1};
> prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
> *(mexGetPr(prhs[0])) = x;
>
> Or, as you almost pointed out, you can use mxCreateDoubleScalar for this:
>
> prhs[0] = mxCreateDoubleScalar(x);
>
> James Tursa


not typos..but plain errors :)
thanks for the corrections.

Subject: mex file wrapper for dll needing function handle

From: Todd Welti

Date: 3 Mar, 2009 22:33:02

Message: 7 of 10

"Ashish Uthama" <first.last@mathworks.com> wrote in message <op.up8j75y1a5ziv5@uthamaa.dhcp.mathworks.com>...
> On Tue, 03 Mar 2009 16:19:03 -0500, James Tursa
> <aclassyguywithaknotac@hotmail.com> wrote:
>
> > "Ashish Uthama" <first.last@mathworks.com> wrote in message
> > <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
> >>
> >> mxCreateScalar will help you convert a double to a mxArray.
> >>
> >> //air code!
> >> mxArray* prhs[3];
> >> mwSize dims[2]={ 1 1};
> >> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
> >> mexGetPr(prhs[0])=x;
> >> //..so on for y and z
> >>
> >
> > Couple of typos. Since dims is an array, it will act as a double * when
> > passed, so you don't need the &dims in the call, just dims. And you are
> > missing a comma in the dims initialization. Also, mxGetPr returns a
> > pointer result that is not an lvalue. You need to dereference it for the
> > assignment. e.g.
> >
> > mxArray* prhs[3];
> > mwSize dims[2]={ 1, 1};
> > prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
> > *(mexGetPr(prhs[0])) = x;
> >
> > Or, as you almost pointed out, you can use mxCreateDoubleScalar for this:
> >
> > prhs[0] = mxCreateDoubleScalar(x);
> >
> > James Tursa
>
>
> not typos..but plain errors :)
> thanks for the corrections.

Thanks for the tips, I'll try it tonight. Also wondering if COM would also work to get the data stream from the third party dll into Matlab, and if there is any advantage? Or if there is any other way that might be better than the callback method I'm currently trying. The data is from a camera based headtracking unit (TrackIR/Optitrack). I have the source code for the dll, but only marginal skills in C++...

Subject: mex file wrapper for dll needing function handle

From: Todd Welti

Date: 4 Mar, 2009 04:11:01

Message: 8 of 10

"Ashish Uthama" <first.last@mathworks.com> wrote in message <op.up8j75y1a5ziv5@uthamaa.dhcp.mathworks.com>...
> On Tue, 03 Mar 2009 16:19:03 -0500, James Tursa
> <aclassyguywithaknotac@hotmail.com> wrote:
>
> > "Ashish Uthama" <first.last@mathworks.com> wrote in message
> > <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
> >>
> >> mxCreateScalar will help you convert a double to a mxArray.
> >>
> >> //air code!
> >> mxArray* prhs[3];
> >> mwSize dims[2]={ 1 1};
> >> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
> >> mexGetPr(prhs[0])=x;
> >> //..so on for y and z
> >>
> >
> > Couple of typos. Since dims is an array, it will act as a double * when
> > passed, so you don't need the &dims in the call, just dims. And you are
> > missing a comma in the dims initialization. Also, mxGetPr returns a
> > pointer result that is not an lvalue. You need to dereference it for the
> > assignment. e.g.
> >
> > mxArray* prhs[3];
> > mwSize dims[2]={ 1, 1};
> > prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
> > *(mexGetPr(prhs[0])) = x;
> >
> > Or, as you almost pointed out, you can use mxCreateDoubleScalar for this:
> >
> > prhs[0] = mxCreateDoubleScalar(x);
> >
> > James Tursa
>
>
> not typos..but plain errors :)
> thanks for the corrections.

Why do you ahve to use the *(mexGetPr())? Isn't prhs already a pointer? Why can't you use *prhs[0]?

Subject: mex file wrapper for dll needing function handle

From: Ashish Uthama

Date: 4 Mar, 2009 13:24:48

Message: 9 of 10

On Tue, 03 Mar 2009 23:11:01 -0500, Todd Welti <twelti@harman.com> wrote:

> "Ashish Uthama" <first.last@mathworks.com> wrote in message
> <op.up8j75y1a5ziv5@uthamaa.dhcp.mathworks.com>...
>> On Tue, 03 Mar 2009 16:19:03 -0500, James Tursa
>> <aclassyguywithaknotac@hotmail.com> wrote:
>>
>> > "Ashish Uthama" <first.last@mathworks.com> wrote in message
>> > <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
>> >>
>> >> mxCreateScalar will help you convert a double to a mxArray.
>> >>
>> >> //air code!
>> >> mxArray* prhs[3];
>> >> mwSize dims[2]={ 1 1};
>> >> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
>> >> mexGetPr(prhs[0])=x;
>> >> //..so on for y and z
>> >>
>> >
>> > Couple of typos. Since dims is an array, it will act as a double *
>> when
>> > passed, so you don't need the &dims in the call, just dims. And you
>> are
>> > missing a comma in the dims initialization. Also, mxGetPr returns a
>> > pointer result that is not an lvalue. You need to dereference it for
>> the
>> > assignment. e.g.
>> >
>> > mxArray* prhs[3];
>> > mwSize dims[2]={ 1, 1};
>> > prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
>> > *(mexGetPr(prhs[0])) = x;
>> >
>> > Or, as you almost pointed out, you can use mxCreateDoubleScalar for
>> this:
>> >
>> > prhs[0] = mxCreateDoubleScalar(x);
>> >
>> > James Tursa
>>
>>
>> not typos..but plain errors :)
>> thanks for the corrections.
>
> Why do you ahve to use the *(mexGetPr())? Isn't prhs already a
> pointer? Why can't you use *prhs[0]?

The return type of mxCreateNumericArray is mxArray *
prhs[0] is mxArray * (think of an mxArray as a structure which represents
the MATLAB matrix type in C)
x is of type double.

To bridge this gap, use this function:
     double *mxGetPr(const mxArray *pm);

mxGetPr(prhs[0]) will give you a double pointer
*(mxGetPr(prhs[0])) will give you access to the value of this double
pointer (the value of MATLAB matrix type). You can then overwrite it with
x since the data type now match.

hth

Subject: mex file wrapper for dll needing function handle

From: Todd Welti

Date: 4 Mar, 2009 17:37:02

Message: 10 of 10

"Ashish Uthama" <first.last@mathworks.com> wrote in message <op.up9rjmqpa5ziv5@uthamaa.dhcp.mathworks.com>...
> On Tue, 03 Mar 2009 23:11:01 -0500, Todd Welti <twelti@harman.com> wrote:
>
> > "Ashish Uthama" <first.last@mathworks.com> wrote in message
> > <op.up8j75y1a5ziv5@uthamaa.dhcp.mathworks.com>...
> >> On Tue, 03 Mar 2009 16:19:03 -0500, James Tursa
> >> <aclassyguywithaknotac@hotmail.com> wrote:
> >>
> >> > "Ashish Uthama" <first.last@mathworks.com> wrote in message
> >> > <op.up8he7c6a5ziv5@uthamaa.dhcp.mathworks.com>...
> >> >>
> >> >> mxCreateScalar will help you convert a double to a mxArray.
> >> >>
> >> >> //air code!
> >> >> mxArray* prhs[3];
> >> >> mwSize dims[2]={ 1 1};
> >> >> prhs[0]=mxCreateNumericArray(2,&dims, mxDOUBLE_CLASS,mxREAL);
> >> >> mexGetPr(prhs[0])=x;
> >> >> //..so on for y and z
> >> >>
> >> >
> >> > Couple of typos. Since dims is an array, it will act as a double *
> >> when
> >> > passed, so you don't need the &dims in the call, just dims. And you
> >> are
> >> > missing a comma in the dims initialization. Also, mxGetPr returns a
> >> > pointer result that is not an lvalue. You need to dereference it for
> >> the
> >> > assignment. e.g.
> >> >
> >> > mxArray* prhs[3];
> >> > mwSize dims[2]={ 1, 1};
> >> > prhs[0]=mxCreateNumericArray(2,dims, mxDOUBLE_CLASS,mxREAL);
> >> > *(mexGetPr(prhs[0])) = x;
> >> >
> >> > Or, as you almost pointed out, you can use mxCreateDoubleScalar for
> >> this:
> >> >
> >> > prhs[0] = mxCreateDoubleScalar(x);
> >> >
> >> > James Tursa
> >>
> >>
> >> not typos..but plain errors :)
> >> thanks for the corrections.
> >
> > Why do you ahve to use the *(mexGetPr())? Isn't prhs already a
> > pointer? Why can't you use *prhs[0]?
>
> The return type of mxCreateNumericArray is mxArray *
> prhs[0] is mxArray * (think of an mxArray as a structure which represents
> the MATLAB matrix type in C)
> x is of type double.
>
> To bridge this gap, use this function:
> double *mxGetPr(const mxArray *pm);
>
> mxGetPr(prhs[0]) will give you a double pointer
> *(mxGetPr(prhs[0])) will give you access to the value of this double
> pointer (the value of MATLAB matrix type). You can then overwrite it with
> x since the data type now match.
>
> hth
>
I think I get it.
mxArray* prhs is a pointer to an mxArray, not the real data in it.

That would explain why my other attempt:

prhs[0] = &x;

didnt' work either.
Thanks

Tags for this Thread

Add a New Tag:

Separated by commas
Ex.: root locus, bode

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

rssFeed for this Thread
 

MATLAB Central Terms of Use

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 Terms prior to use.

Contact us at files@mathworks.com