从C#调用FORTRAN dll并为结构数组赋值
本文关键字:结构 数组 赋值 dll 调用 FORTRAN | 更新日期: 2023-09-27 17:58:17
我可以很好地将C#
结构传递到FORTRAN
中。我甚至可以将C#
结构的数组作为FORTRAN
中TYPE()
的数组传递。当我试图将值返回到C#
时,我遇到了麻烦。这里有一个例子:
fortran dll是:
MODULE TESTING
TYPE VALUEREF
INTEGER*4 :: A
ENDTYPE VALUEREF
CONTAINS
SUBROUTINE TEST_REF(T,N)
!DEC$ ATTRIBUTES DLLEXPORT :: TEST_REF
!DEC$ ATTRIBUTES ALIAS:'TEST_REF' :: TEST_REF
!DEC$ ATTRIBUTES VALUE :: N
IMPLICIT NONE
INTEGER*4 :: A,I,N
TYPE(VALUEREF) :: T(N)
A = 100
DO I=1,N
T(I)%A = A + I
END DO
END SUBROUTINE
END MODULE
并且期望结果的CCD_ 7调用函数是:
[StructLayout(LayoutKind.Sequential)]
public struct ValueRef
{
public int a;
}
[DllImport("mathlib.dll")]
static extern void TEST_REF(ValueRef[] t, int n);
void Main()
{
ValueRef[] T = new ValueRef[4];
for (int i = 0; i < T.Length; i++)
{
T[i].a = i;
}
Console.WriteLine("Initialize");
for (int i = 0; i < T.Length; i++)
{
Console.WriteLine(" A={0}", T[i].a);
}
Console.WriteLine("Call Fortran");
TEST_REF(T, T.Length);
for (int i = 0; i < T.Length; i++)
{
Console.WriteLine(" A={0}", T[i].a);
}
}
结果:
Initialize
A=0
A=1
A=2
A=3
Call Fortran
A=0
A=1
A=2
A=3
通过FORTRAN代码进行调试,我看到初始值从C#
传递到FORTRAN
非常好。这些值被新值覆盖,控制权被传递回C#
,其中旧值仍包含在ValueRef
实例中。
为什么我可以以类似的方式传递并返回一个float
或int
的数组呢。并且我可以用ref
关键字传递和返回奇异结构,并且我可以传递但不能struct
的返回和数组?
PS。我使用的是Compaq Visual Fortran 6.5&NET 3.5
PS2。我很感激对此发表任何意见/想法。我已经完成了95%的项目,现在我遇到了这个问题。这个项目的全部目的是尽可能多地使用结构,以减少传递给函数的参数数量,并保留OOP设计的某些方面。
我过去使用指针而不是数组来完成此操作。我认为您的结构正在被复制用于P/Invoke调用:
[DllImport("mathlib.dll")]
static extern void TEST_REF(ValueRef* t, int n);
在调用该方法之前,您需要固定您的数组。
fixed (ValueRef* pointer = t)
{
TEST_REF(pointer, n);
}
编辑:根据评论,解决方案是将外部声明为
[DllImport("mathlib.dll")]
static extern void TEST_REF([Out] ValueRef[] t, int n);
以下是MSDN关于数组封送的参考,以及它们如何将默认为[In]
。