MATLAB encountered an internal error and needs to close -MEX file

3 次查看(过去 30 天)
I debugged my code based on Mathwork post https://www.mathworks.com/help/matlab/matlab_external/debugging-on-microsoft-windows-platforms.html and crashed MATLAB. This my code:
#include "fintrf.h"
subroutine mexFunction(nlhs, plhs, nrhs, prhs) ! Interface
IMPLICIT REAL*8(A-H,O-Z)
mwpointer plhs(*), prhs(*)
C integer nlhs, nrhs
mwpointer mxCreateDoubleMatrix, mxGetPr
double precision mxGetScalar
C Pointers to input/output mxArrays:
mwPointer TT
C Get the size of the input array.
m_in = 20
n_in = 1
size = m_in * n_in
C Create Fortran array from the input argument.
C IZ = mxGetScalar(prhs(1));
C EEAR = mxGetScalar(prhs(2));
C DDIA = mxGetScalar(prhs(3));
C RRPM = mxGetScalar(prhs(4));
NN = mxGetScalar(prhs(1));
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(m_in, n_in, 0)
TT = mxGetPr(plhs(1))
call LOOPS1(%VAL(TT),%VAL(NN)) ! call the computation
return
end
subroutine LOOPS1(TT, nn)
IMPLICIT REAL*8(A-H,O-Z)
n1 = nn+1
call LOOPS(TT, n1)
return
end
The error is in the line (n1 = nn+1). I don't know what the problem is. Please help me.
  1 个评论
iman AHMADI
iman AHMADI 2016-10-13
Could you please explain me when we use %VAL exactly? Just for outputs or for arrays? I just know it is used instead of mxcopy.

请先登录,再进行评论。

采纳的回答

James Tursa
James Tursa 2016-10-12
编辑:James Tursa 2016-10-12
Some comments:
----------------------------------------------------------------------------------------
IMPLICIT REAL*8(A-H,O-Z)
You need to delete this from your brain and never use it again. Ever. One of the few helps you get with a Fortran compiler for spotting typing issues and variable name misspellings etc is with the following, so use it in all of your code from now on:
IMPLICIT NONE
This will force you to type everything, but it is worth it in the long run.
----------------------------------------------------------------------------------------
C integer nlhs, nrhs
Which means of course you will need to uncomment this line (as well as add typing statements for all of your other untyped variables).
----------------------------------------------------------------------------------------
m_in = 20
n_in = 1
:
plhs(1) = mxCreateDoubleMatrix(m_in, n_in, 0)
Unlike C/C++, you do not get automatic argument promotion in Fortran ... especially for implicit interfaces. So you should always use the exact types specified in the documented signature and never use explicit constants in argument lists. E.g., the signature for mxCreateDoubleMatrix is:
mwPointer mxCreateDoubleMatrix(m, n, ComplexFlag)
mwSize m, n
integer*4 ComplexFlag
So your code should follow this signature exactly. E.g.,
mwSize m_in, n_in
integer*4 :: ComplexFlag = 0
:
m_in = 20
n_in = 1
:
plhs(1) = mxCreateDoubleMatrix(m_in, n_in, ComplexFlag)
----------------------------------------------------------------------------------------
size = m_in * n_in
size is the name of an intrinsic function in Fortran. You should pick a different name for your variable.
----------------------------------------------------------------------------------------
call LOOPS1(%VAL(TT),%VAL(NN)) ! call the computation
TT is holding a pointer value, but NN is just an integer variable (not holding a pointer to a integer variable). So you should not be passing NN by value here (this error is what is causing your crash). E.g., you should be doing this instead:
call LOOPS1(%VAL(TT),NN) ! call the computation
----------------------------------------------------------------------------------------
  2 个评论
iman AHMADI
iman AHMADI 2016-10-13
编辑:iman AHMADI 2016-10-13
Thank you very much James. It worked! Could you please tell me when we should exactly use %VAL? Just for outputs(arrays and scalars) or in another place? I just know that it is used instead of mxcopy.
James Tursa
James Tursa 2016-10-14
编辑:James Tursa 2016-10-14
The following API functions return mwPointer types that hold memory addresses: mxGetPr, mxGetPi, mxGetData, mxGetImagData, mxGetIr, mxGetJc, mxGetDimensions. Anytime you are passing the result of these calls to another Fortran routine that is expecting a normal intrinsic type (like REAL, REAL(8), INTEGER, INTEGER(8), etc), you should use the %VAL( ) construct in the calling routine. Basically, you want to put the address of the data on the stack since that is what the other Fortran routine is expecting (for implicit interfaces) to get on the stack.

请先登录,再进行评论。

更多回答(1 个)

iman AHMADI
iman AHMADI 2016-10-14
编辑:iman AHMADI 2016-10-14
Thank you again. I write another code but the code just get the first output!! This is my code:
#include "fintrf.h"
#if 0
C
C Ship.F
C .F file needs to be preprocessed to generate .for equivalent
C
#endif
C=======================================================================
C Gateway subroutine
subroutine mexfunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix
mwPointer mxGetM, mxGetN
real*8 mxGetScalar
C Pointers to input/output mxArrays:
mwPointer pr_out1, pr_out2
C Array information:
integer m_in1, n_in1
integer m_in2, n_in2
integer*4 :: ComplexFlag = 0
real*8 pr_in1
m_in1 = 1
n_in1 = 1
m_in2 = 1
n_in2 = 1
C Create Fortran array from the input argument.
pr_in1 = mxGetScalar(prhs(1));
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(m_in1, n_in1, ComplexFlag)
pr_out1 = mxGetPr(plhs(1))
plhs(2) = mxCreateDoubleMatrix(m_in2, n_in2, ComplexFlag)
pr_out2 = mxGetPr(plhs(2))
call image1(%VAL(pr_out1),%VAL(pr_out2),pr_in1) ! call the computation
return
end
subroutine image1(C_Res, Fr_N, pr_in1)
IMPLICIT REAL*8(A-H,O-Z)
COMMON /FNCW/FNN, CWW, Fr_in
.
.
.
Fr_in = pr_in1
.
.
.
CALL FSPNLP2(NSPC)
.
.
.
CALL WAVE1
C_Res = CWW
Fr_N = FNN
.
.
.
RETURN
END
SUBROUTINE FSPNLP2(NSPC)
IMPLICIT REAL*8(A-H,O-Z)
COMMON /CONDP/FN
COMMON /FNCW/FNN,CWW,Fr_in
FN = Fr_in
.
.
.
RETURN
END
SUBROUTINE WAVE1
IMPLICIT REAL*8(A-H,O-Z)
COMMON /CONDP/ FN
COMMON /FNCW/FNN,CWW,Fr_in
.
.
.
C After calculating CW
CWW=CW
FNN=FN
RETURN
END
I wrote in command window f=0.2;image(fn) and just got the first output(CW). the input and second output(FN) are identical. I need FN to be sure that the input won't change during several CALLs. Do you think this is because of using IMPLICIT REAL*8(A-H,O-Z)?
  1 个评论
James Tursa
James Tursa 2016-10-14
I am not sure I understand the problem. You show the following for how you are calling the function:
f=0.2;image(fn)
If "image" is the name of your mex routine and you want to get both outputs back to the workspace, you need to call it with two outputs (just like you would call any other function that has two outputs). E.g.,
f=0.2;
[out1,out2] = image(fn); % <-- provide two variable names to store the result

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Fortran with MATLAB 的更多信息

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by