Can't use allocate command in Fortran Mex file
5 ビュー (過去 30 日間)
古いコメントを表示
If I delete allocate, this file can be compiled successfully, but when I added the allocate, it will be an error. My matlab version is R2016b, and fortran version is GFORTRAN (GCC 6.3.0) and Xcode 7.3. The details are following. What should I do if I need to keep allocate?
#include<fintrf.h>
subroutine MEXFUNCTION(nlhs, plhs, nrhs, prhs)
implicit none
MWPOINTER :: plhs(*), prhs(*)
MWPOINTER :: mxCreateDoubleMatrix, mxGetPr
MWPOINTER :: something
integer :: nrhs, nlhs, nargin, nargout
mwSignedIndex :: num
real*8 mxGetScalar
! plhs(1) = mxCreateDoubleMatrix(zero,zero,mxREAL)
!Check for proper number of arguments
nargin = 1
nargout = 1
if(nrhs .ne. nargin) then
call mexErrMsgTxt('One input required.')
elseif(nlhs .gt. nargout) then
call mexErrMsgTxt('Too many outputs.')
end if
num = int(mxGetScalar(prhs(1)))
plhs(1) = mxCreateDoubleMatrix(num, num, 0)
something = mxGetPr(plhs(1))
! Call computational subroutine:
call make_matrix(num, %val(something))
return
end
subroutine make_matrix(num, something)
implicit none
integer :: num, i, j
real(kind = 8), allocatable :: something2(:, :)
real(kind = 8) :: something(num, num)
allocate(something2(num, num))
do i = 1, num
do j = 1, num
something2(i, j) = i * j
end do
end do
CALL DLACPY('ALL', num, num, something2, num, something, num)
deallocate(something2)
return
end
The error is :
Undefined symbols for architecture x86_64:
"__gfortran_os_error", referenced from:
_make_matrix_ in make_matrix.o
"__gfortran_runtime_error", referenced from:
_make_matrix_ in make_matrix.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1
(use -v to see invocation)
0 件のコメント
採用された回答
James Tursa
2017 年 10 月 31 日
編集済み: James Tursa
2017 年 10 月 31 日
First thing you should do is clean up your argument typing to be consistent. You have the following:
mwSignedIndex :: num
:
call make_matrix(num, %val(something))
:
subroutine make_matrix(num, something)
integer :: num, i, j
It is entirely possible that the "mwSignedIndex" type is a 64-bit integer while the default "integer" type is a 32-bit integer ... even on a 64-bit system. Since the make_matrix subroutine is using an implicit interface, the compiler/linker will not catch this potential error. You should always ensure you have the same argument types, so maybe change that declaration in the subroutine to:
mwSignedIndex :: num, i, j
You may need to change that call to DLACPY as well.
Next thing you should do is NEVER use literal constants in Fortran for the arguments to the MATLAB API functions. You can get away with this in C/C++ where arguments are passed by value and you get automatic type promotion from the compiler ... but you can't get away with this in Fortran where you might have a mismatch since arguments are effectively passed by reference. Again, one typical cause is the 64-bit integer vs 32-bit integer thing. So always use the exact type specified in the API signature. In this case, the signature for mxCreateDoubleMatrix is this:
mwPointer mxCreateDoubleMatrix(m, n, ComplexFlag)
mwSize m, n
integer*4 ComplexFlag
So you should change your code to use these exact variable types, and always pass a variable and not a literal constant. So change this:
mwSignedIndex :: num
:
num = int(mxGetScalar(prhs(1)))
plhs(1) = mxCreateDoubleMatrix(num, num, 0)
to something like this:
mwSignedIndex :: num
mwSize m, n
integer*4 ComplexFlag
:
num = int(mxGetScalar(prhs(1)))
m = num
n = num
ComplexFlag = 0
plhs(1) = mxCreateDoubleMatrix(m, n, ComplexFlag)
After making these changes to ensure it is not an argument type mismatch issue, then we can work on the allocate/deallocate issue. You should probably put in a memory allocation failure check in your code for the allocate statement, btw.
その他の回答 (0 件)
参考
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!