如何解决在 Fortran 中调用 StdCall 子例程
我在一个 DLL 中有两个子例程。要在 C# 中调用它们,请将它们更改为 STDCALL,如下所示:
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
像这样,我还需要在MoveToZero
中调用GetApparent
,但是出现错误:
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]
那么,如何在 Fortran 中调用 stdcall 子程序?
解决方法
我不能说 C#,但这里的问题是你在 Fortran 中调用 stdcall 子例程而不声明其接口:CALL MoveToZero(x,size(x))
。
您必须在 GetApparent 的主体中声明 MoveToZero 的接口,例如可以使用接口块来完成:
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
您也可以使用接口模块(即只有那些接口块的模块)并在需要这些声明的所有过程中使用它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。