0

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?

Chen
  • 33
  • 1
  • 5
  • Please provide the full interface of the Fortran functions. Also, if I gave you a C equivalent of these functions, would you be able to call the C functions from C#? – Scientist Jul 12 '21 at 02:39

1 Answers1

1

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.