From: James Tursa on
"Etienne" <etienne.coetzee(a)airbus.com> wrote in message <hka85a$sbe$1(a)fred.mathworks.com>...
>
> I have spent the whole day going through mex fortran exercises, and have a better idea of how the mex functions work. I am not a Fortran guru, but am having to hack somebody else's fortran code. I now want to use an object to set some simulation parameters for the fortran program. The fortran program then goes away, runs, and I want to write the final results back to the object. I thought I had it worked out, but I am still getting a problem when I use the mxGetPropery and mxSetProperty. I'll keep on trying.

I just tried mxGetProperty and mxSetProperty with Intel 9.1 on WinXP 32-bit and they seem to work just fine. However, I did discover a couple of things:

1) I did not have an interface for mxSetProperty in my Fortran 95 interface code submission on the FEX. Sorry about that. I will fix that up and resubmit it.

2) The doc for mxSetProperty is wrong. The doc reads:

C Syntax

#include "matrix.h"
void mxSetProperty(mxArray *pa, mwIndex index,
const char *propname, const mxArray *value);

Fortran Syntax

mwPointer mxSetProperty(pa, index, propname, value)
mwPointer pa, value
mwIndex index
character*(*) propname

You can clearly see from the C syntax that the routine doesn't return anything. So the interface for Fortran should be a subroutine, not a function. e.g.,

subroutine mxSetProperty(pa, index, propname, value)
mwPointer pa, value
mwIndex index
character*(*) propname

What specific problems are you having with using these routines? Would it help if I posted a short example? I will repeat that these functions are for use with the new style objects (all of the properties and methods in one file), not with the old style objects (many files in a @classname directory).

James Tursa
From: Etienne on
"James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hkad6i$s31$1(a)fred.mathworks.com>...
> "Etienne" <etienne.coetzee(a)airbus.com> wrote in message <hka85a$sbe$1(a)fred.mathworks.com>...
> >
> > I have spent the whole day going through mex fortran exercises, and have a better idea of how the mex functions work. I am not a Fortran guru, but am having to hack somebody else's fortran code. I now want to use an object to set some simulation parameters for the fortran program. The fortran program then goes away, runs, and I want to write the final results back to the object. I thought I had it worked out, but I am still getting a problem when I use the mxGetPropery and mxSetProperty. I'll keep on trying.
>
> I just tried mxGetProperty and mxSetProperty with Intel 9.1 on WinXP 32-bit and they seem to work just fine. However, I did discover a couple of things:
>
> 1) I did not have an interface for mxSetProperty in my Fortran 95 interface code submission on the FEX. Sorry about that. I will fix that up and resubmit it.
>
> 2) The doc for mxSetProperty is wrong. The doc reads:
>
> C Syntax
>
> #include "matrix.h"
> void mxSetProperty(mxArray *pa, mwIndex index,
> const char *propname, const mxArray *value);
>
> Fortran Syntax
>
> mwPointer mxSetProperty(pa, index, propname, value)
> mwPointer pa, value
> mwIndex index
> character*(*) propname
>
> You can clearly see from the C syntax that the routine doesn't return anything. So the interface for Fortran should be a subroutine, not a function. e.g.,
>
> subroutine mxSetProperty(pa, index, propname, value)
> mwPointer pa, value
> mwIndex index
> character*(*) propname
>
> What specific problems are you having with using these routines? Would it help if I posted a short example? I will repeat that these functions are for use with the new style objects (all of the properties and methods in one file), not with the old style objects (many files in a @classname directory).
>
> James Tursa

Hi James

An example would be very useful. I am using the new objects. I tried to write some code where I take a field, multiply it by two, and then send the object back out. I am assuming that I catually need to make a deep copy of the object that I am passing in, and then set the properties of the copied object. I couldn't get it to work though.

Etienne
From: Etienne on
Hi James

My attempt is here. It falls over when I try

CALL mxCopyPtrToInteger4(ptrNDIM,NDIM,1)

Obviously I am doing something wrong.

Regards

Etienne

====================================================
#include <fintrf.h>
C
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
C
IMPLICIT NONE
MWPOINTER PLHS(*), PRHS(*)
INTEGER NLHS, NRHS
C
C-----------------------------------------------------
INTEGER NDIM,MATNDIM
mwPointer mxGetProperty,mxGetPr,mxDuplicateArray
mwPointer ptrPRHS,ptrPLHS,ptrNDIM
C
ptrPRHS=mxGetPr(PRHS(1))
PLHS(1)=mxDuplicateArray(PRHS(1))
ptrPLHS=mxGetPr(PLHS(1))
C
ptrNDIM=mxGetProperty(ptrPLHS,1,'Ndim')
CALL mxCopyPtrToInteger4(ptrNDIM,NDIM,1)
C
MATNDIM=2*NDIM
CALL mxCopyInteger4ToPtr(MATNDIM,ptrNDIM,1)
CALL mxSetProperty(ptrPLHS,1,'Ndim',ptrNDIM)
C-----------------------------------------------------
C
RETURN
END
From: James Tursa on
"Etienne" <etienne.coetzee(a)airbus.com> wrote in message <hkbfl0$s7l$1(a)fred.mathworks.com>...
> Hi James
>
> My attempt is here. It falls over when I try
>
> CALL mxCopyPtrToInteger4(ptrNDIM,NDIM,1)
>
> Obviously I am doing something wrong.
>
> Regards
>
> Etienne
>
> ====================================================
> #include <fintrf.h>
> C
> SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
> C
> IMPLICIT NONE
> MWPOINTER PLHS(*), PRHS(*)
> INTEGER NLHS, NRHS
> C
> C-----------------------------------------------------
> INTEGER NDIM,MATNDIM
> mwPointer mxGetProperty,mxGetPr,mxDuplicateArray
> mwPointer ptrPRHS,ptrPLHS,ptrNDIM
> C
> ptrPRHS=mxGetPr(PRHS(1))
> PLHS(1)=mxDuplicateArray(PRHS(1))
> ptrPLHS=mxGetPr(PLHS(1))
> C
> ptrNDIM=mxGetProperty(ptrPLHS,1,'Ndim')
> CALL mxCopyPtrToInteger4(ptrNDIM,NDIM,1)
> C
> MATNDIM=2*NDIM
> CALL mxCopyInteger4ToPtr(MATNDIM,ptrNDIM,1)
> CALL mxSetProperty(ptrPLHS,1,'Ndim',ptrNDIM)
> C-----------------------------------------------------
> C
> RETURN
> END

You are not thinking about the object properly. An object is not like a numeric variable. Numeric variables have numeric data areas, and pointers to those numeric data areas can be obtained with the mxGetPr, mxGetPi, mxGetData, and mxGetImagData functions. You can't do that with an object like you are trying to do. i.e., these lines makes no sense if PRHS(1) is an object:

> ptrPRHS=mxGetPr(PRHS(1))
> PLHS(1)=mxDuplicateArray(PRHS(1))
> ptrPLHS=mxGetPr(PLHS(1))

because what is mxGetPr supposed to return? There is no numeric data area of the object. There are properties, and each of *those* properties may have numeric data areas. That is what you should be doing.

You need to get the property extracted from the object first, and then you will have a double or int32 (or whatever) variable to work with. e.g., assuming the input PRHS(1) is a new-style object with a property named Ndim that is a int32 class variable (caveat, the following is untested):

#include <fintrf.h>
C
SUBROUTINE MEXFUNCTION(NLHS, PLHS, NRHS, PRHS)
C
IMPLICIT NONE
MWPOINTER PLHS(*), PRHS(*)
INTEGER NLHS, NRHS
C
C-----------------------------------------------------
INTEGER*4 NDIM, MATNDIM
mwPointer mxGetProperty, mxGetPr, mxDuplicateArray
mwPointer ptrNDIM, ptrNDIMpr
C
PLHS(1)=mxDuplicateArray(PRHS(1)) ! PLHS(1) is an object mxArray
ptrNDIM=mxGetProperty(PLHS(1),1,'Ndim') ! ptrNDIM is an int32 mxArray
ptrNDIMpr=mxGetPr(ptrNDIM) ! ptrNDIMpr points to the int32 data
C
CALL mxCopyPtrToInteger4(ptrNDIMpr,NDIM,1) ! extract the integer*4 value
MATNDIM=2*NDIM ! double it
CALL mxCopyInteger4ToPtr(MATNDIM,ptrNDIMpr,1) ! replace the integer*4 value
CALL mxSetProperty(PLHS(1),1,'Ndim',ptrNDIM) ! set the new property
CALL mxDestroyArray(ptrNDIM) ! destroy our temporary mxArray for NDIM
C-----------------------------------------------------
C
RETURN
END

Although not shown, in practice you would want to put in a lot of checks for variable types & sizes etc so that your program would not bomb on unexpected input data.

James Tursa
From: Etienne on
Thanks James

I will take a look at it tomorrow.

Cheers

Etienne