如何通过Fortran';将s复杂类型转换为C#?

如何通过Fortran';将s复杂类型转换为C#?,c#,fortran,pinvoke,gfortran,C#,Fortran,Pinvoke,Gfortran,假设我有下面的Fortran代码 subroutine COMPLEX_传递(r,i,c) !DEC$ATTRIBUTES DLLEXPORT::复杂的\u传递 真实*8::r,i 复合*8::c c=cmplx((r*2),(i*2)) 返回 结束 Fortran代码是用 gfortran -c complex_passing.f90 gfortran -fPIC -shared -o complex_passing.dll complex_passing.o 我如何在C#中调用这个子程序

假设我有下面的Fortran代码

subroutine COMPLEX_传递(r,i,c)
!DEC$ATTRIBUTES DLLEXPORT::复杂的\u传递
真实*8::r,i
复合*8::c
c=cmplx((r*2),(i*2))
返回
结束
Fortran代码是用

gfortran -c complex_passing.f90
gfortran -fPIC -shared -o complex_passing.dll complex_passing.o
我如何在C#中调用这个子程序?我尝试了以下代码:

使用系统;
使用System.Runtime.InteropServices;
名称空间FortranCalling{
班级计划{
静态void main(字符串[]参数){
双实数=4;
双虚=10;
复合物c=新复合物();
复数_传递(ref real,ref virtual,refc);
WriteLine(“Real:{0}\nImaginary:{1}”,c.Real,c.virtual);
Console.ReadLine();
}
[StructLayout(LayoutKind.Sequential)]
结构复合体{
公共双实;
公众双重想象;
}
[DllImport(“complex_passing.dll”,EntryPoint=“complex_passing”,CallingConvention=CallingConvention.Cdecl)]
静态外部空隙复合体_通过(参考双r、参考双i、参考复合体c);
}
}
几乎没有成功-我的复杂结构似乎正在返回垃圾数据:

Real: 134217760.5
Imaginary: 0

当我期望实部为8,虚部为20时。

gfortran将非标准的
复数*8
视为大小为8字节的复数,实部和虚部各有4字节。相反,您需要一个16字节的复数,实数和虚数分量各为8字节(
complex*16
),或者您应该相应地更改C端

在gfortran下的以下内容中可以看到这一效果:

complex*8::c8=(8d0,20d0)
复杂*16::c16=0
c16%re=转移(c8,c16)
打印*,c8,c16
结束
当然,您根本不应该使用
complex*
。参数不匹配可以使用
complex(kind=…)
来查看

考虑以下“Fortran”源代码:

子程序s(r,i,c)
真实(种类(0d0)):r,i
复合物(种类(0e0))::c
c=cmplx((r*2),(i*2))
结束子程序
接口!某些版本的gfortran需要接口块
子程序s(r,i,c)
真实(种类(0d0)):r,i
复合物(种类(0d0))::c
结束子程序
端接口
络合物(类(0d0))c
呼叫s(4d0,10d0,c)
打印*,c%re
结束
并将其与Fortran源代码进行比较:

子程序s(r,i,c)
真实(种类(0d0)):r,i
复合物(种类(0d0))::c
c=cmplx((r*2),(i*2))
结束子程序
络合物(类(0d0))c
呼叫s(4d0,10d0,c)
打印*,c%re
结束
此外,与其使用
kind(0d0)
等,不如使用
iso\u fortran\u env
的各种C互操作性常数和存储大小常数