Path: news.mathworks.com!not-for-mail
From: <HIDDEN>
Newsgroups: comp.soft-sys.matlab
Subject: Re: Call a MEX function from Matlab Engine?
Date: Fri, 14 Mar 2008 00:34:01 +0000 (UTC)
Organization: Boeing
Lines: 126
Message-ID: <frch5p$bdj$1@fred.mathworks.com>
References: <frc4bp$ipi$1@fred.mathworks.com> <frc7ir$s19$1@fred.mathworks.com> <frccfq$l2f$1@fred.mathworks.com>
Reply-To: <HIDDEN>
NNTP-Posting-Host: webapp-03-blr.mathworks.com
Content-Type: text/plain; charset="ISO-8859-1"
Content-Transfer-Encoding: 8bit
X-Trace: fred.mathworks.com 1205454841 11699 172.30.248.38 (14 Mar 2008 00:34:01 GMT)
X-Complaints-To: news@mathworks.com
NNTP-Posting-Date: Fri, 14 Mar 2008 00:34:01 +0000 (UTC)
X-Newsreader: MATLAB Central Newsreader 756104
Xref: news.mathworks.com comp.soft-sys.matlab:457156




I don't know if you need this much advice, but here 
goes ...

"David Doria" <daviddoria@gmail.com> wrote in message 
<frccfq$l2f$1@fred.mathworks.com>...
> 
> 2) I mentioned that test(4) in matlab outputs 16, but I
> actually dont remember now if it returned an int or a
> double(i'll check in the morning). I figured that matlab
> would convert it to its "matrix" class anyway - does it 
not?

There is no such thing as a "matrix" class. The class 
types are things 
like "double", "single", "int32", "int16", etc. Variables 
of these class types can be scalars, vectors, matrices, or 
multi-dimensional arrays. If you type in a constant 
number, like the argument 4 in your test(4) call, MATLAB 
will convert the 4 into an mxArray of type double class, 
with dimensions 1 x 1 (i.e. scalar). This is what gets 
passed to the test function. If test is a mex function, 
then that means that prhs[0] will be a pointer to an 
mxArray of type double with one element. There is no 
automatic conversion as far as accessing this data is 
concerned. It is a 64-bit floating point value and needs 
to be treated as such in your C++ code. There are various 
ways to get the scalar value for use in your C++ code:

    double d;
    double *dp;
    dp = mxGetPr(prhs[0]);
    d = *dp;

or

    double d;
    double *dp;
    dp = (double *) mxGetData(prhs[0]);
    d = *dp;

or

    double d;
    d = *(mxGetPr(prhs[0]));

If you know the input has an integer value and want to use 
it as an int, you can use a cast to do this, for instance

    int i;
    i = (int) *(mxGetPr(prhs[0]));

but you CANNOT do something like this

    int i;
    int *ip;
    ip = mxGetPr(prhs[0]); // bad bad bad
    i = *ip;

and the use of a cast doesn't fix this either

    int i;
    int *ip;
    ip = (int *) mxGetPr(prhs[0]); // bad bad bad
    i = *ip;

These last two cases takes the result of mxGetPr, which is 
always a pointer to double, and then subsequently treats 
it as a pointer to int when dereferencing. Since the 
underlying bits are 64-bit floating point this will give 
you garbage.

Same comments apply to the output of your mex function. 
plhs[0] is created by you with whatever class type you 
select. If you use mxCreateDoubleMatrix, for instance, 
then the class will be double and the data will be 64-bit 
floating point and must be treated as such. If your C++ 
code returns an int that you want stuffed into plhs[0], 
then you would have to make sure it was cast either 
explicitly or implicitly. For example suppose MyFunc 
returns an int:

    int i;
    plhs[0] = mxCreateDoubleMatrix( 1, 1, mxREAL );
    i = MyFunc( blah blah );
    *(mxGetPr(plhs[0])) = (double) i;

Here we are getting an int result from MyFunc, casting 
that result into a double, and then putting that into the 
data area of plhs[0]. You don't actually *need* the 
(double) cast in this assignment since it will happen 
automatically in this case, but I think it is good 
practice to put these in your code to make them obvious to 
the reader what is going on.

> Would I just change double *myout2; to int *myout2? 
> Assuming the function did return an int, in this case it
> should be converting from an int to a double, can it not 
do
> that automatically?
> 

See the above comments. You can certainly cast a double to 
an int, but you cannot cast a pointer to double into a 
pointer to int and then expect to get a correct answer 
when dereferencing it.

I suggest you post your mex code so that I can look at it 
and see what you are doing.

> 2b) If I use mxGetData instead of mxGetPr does that kind 
of
> fix the type automatically?
> 

No. mxGetData returns a pointer to void, whereas mxGetPr 
returns a pointer to double, but they both return the same 
value. i.e., the address they return is the same, namely 
the starting address of the data.  mxGetPr should only be 
used with mxArrays of class double, and mxGetData should 
be used for all other classes (single, int32, etc.) and 
then a cast used ((float *), (int *), etc.) on the result 
to get proper access to the data.

James Tursa