Not sure what you are asking. Are you simply asking how to populate the variables in a COMMON block with data generated on the MATLAB side? e.g., are you trying to write a mex function that passes in MATLAB variables and then calls a Fortran subroutine that takes part or all of its input from COMMON blocks? If so, I can help with that.
James Tursa
Yes, that is correct. I am trying to call a fortran routine from Matlab that requires information from a COMMON block. I need to create and populate that block from Matlab.
Scott
I will offer two methods. Both of them involve copying, which can't be avoided if you want to retain the COMMON block interface. The first uses only stock MATLAB API routines. The second uses my Fortran 95 Interface routines which can be found here:
Both take a 5-element double vector, multiply it by 2, and return the result.
James Tursa
--------------------------------------------------------------------------------------------
Call the 1st file e.g. common1.f and compile it with
mex common1.f
Run it with
common1([1 2 3 4 5])
--------------------------------------------------------------------------------------------
#include "fintrf.h"
#ifndef mwSize
#define mwSize integer*4
#endif
#ifndef mwPointer
#define mwPointer integer*4
#endif
!---------------------------------------------------------------------
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
implicit none
!-ARG
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
!-FUN
mwPointer, external :: mxGetPr
mwPointer, external :: mxCreateDoubleMatrix
integer*4, external :: mxIsDouble
mwSize, external :: mxGetNumberOfElements
mwSize, external :: mxGetM
mwSize, external :: mxGetN
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-LOC
mwSize :: m, n
integer*4 :: mxREAL = 0
mwPointer pr
logical ok
!-----
ok = .false.
if( nrhs == 1 ) then
if( mxIsDouble(prhs(1)) == 1 ) then
if( mxGetNumberOfElements(prhs(1)) == 5 ) then
ok = .true.
endif
endif
endif
if( .not.ok ) then
call mexErrMsgTxt("Need one 5-element double input")
endif
if( nlhs > 1 ) then
call mexErrMsgTxt("Too many outputs")
endif
pr = mxGetPr(prhs(1))
m = mxGetM(prhs(1))
n = mxGetN(prhs(1))
call mxCopyPtrToReal8(pr, inarray, m*n)
call sub
plhs(1) = mxCreateDoubleMatrix(m, n, mxREAL)
pr = mxGetPr(plhs(1))
call mxCopyReal8ToPtr(outarray, pr, m*n)
end subroutine mexFunction
!---------------------------------------------------------------
subroutine sub
implicit none
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-----
outarray = 2.d0 * inarray
end subroutine sub
--------------------------------------------------------------------------------------------
Call the 2nd file e.g. common2.f and compile it with
mex -c MatlabAPImex.f
mex -c MatlabAPImx.f
mex common2.f MatlabAPImex.obj MatlabAPImx.obj
Run it with
common2([1 2 3 4 5])
--------------------------------------------------------------------------------------------
#include "fintrf.h"
#ifndef mwSize
#define mwSize integer*4
#endif
#ifndef mwPointer
#define mwPointer integer*4
#endif
!---------------------------------------------------------------------
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
use MatlabAPImex
use MatlabAPImx
implicit none
!-ARG
mwPointer plhs(*), prhs(*)
integer*4 nlhs, nrhs
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-LOC
real(8), pointer :: fp(:)
!-----
if( nrhs /= 1 ) goto 900
if( nlhs > 1 ) then
call mexErrMsgTxt("Too many outputs")
endif
fp => fpGetPr1(prhs(1))
if( .not.associated(fp) ) goto 900
if( size(fp) /= 5 ) goto 900
inarray = fp
call sub
plhs(1) = mxArray(outarray, orient="row")
return
900 call mexErrMsgTxt("Need one 5-element double input")
end subroutine mexFunction
!---------------------------------------------------------------
subroutine sub
implicit none
!-COM
real(8) inarray(5), outarray(5)
common /stuff/ inarray, outarray
!-----
outarray = 2.d0 * inarray
end subroutine sub
Scott,
I know this isn't what you originally asked, but you may consider
converting the fortran to matlab code. I wrote f2matlab to do this
kind of thing, and it can handle common blocks. It is at the file
exchange:
http://www.mathworks.com/matlabcentral/fileexchange/5260
Let me know if you run into problems,
Ben Barrowes
James,
Thanks for the suggestion. This worked out well.
Scott
Ben,
Thanks for the suggestion. I will let you know of any problems.
Scott