I've been struggling to find a way to allocate an array in my Fortran Mex function and return it to Matlab. Every variation I attempt crashes, usually at the return of the Mex function. I have made a trivial example that reproduces the crux of the issue.
My first thought was just to use allocatable arrays, but that crashes upon calling the make_matrix routine. Then I tried mxCalloc, but I couldn't figure out how to make that not crash upon returning from the Mex function. My last attempts (illustrated below) were to try to use mxGetPr or mxSetPr, but any variation on that just crashes as well. I can't find an example of any of these ideas in Fortran anywhere. How does one accomplish this? It seems like it should be simple.
#include<fintrf.h>subroutine MEXFUNCTION(nlhs, plhs, nrhs, prhs)implicit noneMWPOINTER :: plhs(*), prhs(*)MWPOINTER :: mxCreateDoubleMatrix, mxGetPrMWPOINTER :: Pr(1), somethinginteger(kind = 4) :: nrhs, nlhs, nargin, nargout, jarg, num_i4!Check for proper number of argumentsnargin = 1nargout = 1if(nrhs .ne. nargin) then call mexErrMsgTxt('Wrong # inputs found - expecting 1')elseif(nlhs .ne. nargout) then call mexErrMsgTxt('Wrong # outputs found - expecting 1')end ifdo jarg = 1, nargin Pr(jarg) = mxGetPr(prhs(jarg))end do! Call computational subroutine:call make_matrix(%val(Pr(1)), something, num_i4)
! Create the output array:call mxSetPr(plhs(1), something)!plhs(1) = mxGetPr(something)returnendsubroutine make_matrix(num, something, num_i4)implicit nonemwPointer :: mxCreateDoubleMatrixreal(kind = 8), intent(in) :: numinteger(kind = 4), intent(out) :: num_i4integer(kind = 4) :: i, jmwPointer :: somethingreal(kind = 8), allocatable :: something_r8(:, :)num_i4 = int(num)allocate(something_r8(num_i4, num_i4))do i = 1, num_i4 do j = 1, num_i4 something_r8(i, j) = i * j end doend dosomething = mxCreateDoubleMatrix(num_i4, num_i4, 0)call mxCopyReal8ToPtr(something_r8, something, size(something_r8))deallocate(something_r8)returnend
Best Answer