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.
MATLAB encountered an internal error and needs to close -MEX file
3 visualizzazioni (ultimi 30 giorni)
Mostra commenti meno recenti
iman AHMADI
il 12 Ott 2016
Modificato: James Tursa
il 14 Ott 2016
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.
Risposta accettata
James Tursa
il 12 Ott 2016
Modificato: James Tursa
il 12 Ott 2016
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 Commenti
James Tursa
il 14 Ott 2016
Modificato: James Tursa
il 14 Ott 2016
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.
Più risposte (1)
iman AHMADI
il 14 Ott 2016
Modificato: iman AHMADI
il 14 Ott 2016
1 Commento
James Tursa
il 14 Ott 2016
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
Vedere anche
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!