I have two subroutines in a DLL. To call them in C#, they are changed to STDCALL like this:
SUBROUTINE MoveToZero(X, N)
!DEC$ ATTRIBUTES DLLEXPORT::MoveToZero
!DEC$ ATTRIBUTES STDCALL,ALIAS:'RemoveBias'::MoveToZero
USE MKL_DFTI
INTEGER :: N
DOUBLE PRECISION :: X(N)
DOUBLE COMPLEX :: Y(N / 2 + 1)
type(DFTI_DESCRIPTOR), POINTER :: des
status = DftiCreateDescriptor(des, DFTI_DOUBLE, DFTI_REAL, 1, N)
status = DftiSetValue(des, DFTI_PLACEMENT, DFTI_NOT_INPLACE)
status = DftiCommitDescriptor(des)
status = DftiComputeForward(des, X, Y)
Y(1) = 0
status = DftiComputeBackward(des, Y, X)
status = DftiFreeDescriptor(des)
X = X / N
END
SUBROUTINE GetApparent(current, voltage, N, output)
!DEC$ ATTRIBUTES DLLEXPORT::GetApparent
!DEC$ ATTRIBUTES STDCALL,ALIAS:'GetApparent'::GetApparent
INTEGER :: N
INTEGER ,PARAMETER :: M = 5
DOUBLE PRECISION :: current(N), voltage(N)
DOUBLE PRECISION :: output(M)
CALL MoveToZero(current, size(current)) ! This line raise an error
End
Like this, I also need to call MoveToZero
in GetApparent
, but there is an error:
1>D:\Integrate\ProcessModule\Source1.f90(29): error #7519:
Required explicit interface for a procedure with C or STDCALL
attribute is missing from original source. [MOVETOZERO]
So, how to call a stdcall subroutine in Fortran?
I can't say for C#, but the problem here is that you call, in Fortran, a stdcall subroutine without declaring its interface: CALL MoveToZero(x, size(x))
.
You have to declare the MoveToZero's interface in the body of GetApparent, which can be done with an interface block for instance:
SUBROUTINE GetApparent(current, voltage, N, output)
!DEC$ ATTRIBUTES DLLEXPORT::GetApparent
!DEC$ ATTRIBUTES STDCALL,ALIAS:'GetApparent'::GetApparent
INTERFACE
SUBROUTINE MoveToZero(X, N)
!DEC$ ATTRIBUTES DLLEXPORT::MoveToZero
!DEC$ ATTRIBUTES STDCALL,ALIAS:'RemoveBias'::MoveToZero
!**** Declare type of X and N ****
END SUBROUTINE
END INTERFACE
!...Some Codes
CALL MoveToZero(n, n)
!...Some Codes
END
You may also use an interface module (i.e. a module with only those interface blocks) and USE it in all procedures that need these declarations.