我想将FORTRAN DLL导入Visual C#。虽然我已经使用函数完成了这项工作,但是当我想导入具有多个输出的子例程时会出现问题。这是一个简单的例子:
FORTRAN DLL:
Subroutine MySub(a,b,x,y)
!DEC$ ATTRIBUTES DLLEXPORT, STDCALL, ALIAS:'MySub' :: MySub
Implicit None
Integer, INTENT(IN) :: a,b
Integer, INTENT(OUT) :: x,y
y=a+b
x=2*a+3*b
End Subroutine MySub
C#Console App:
using System;
using System.Runtime.InteropServices;
namespace AlReTest
{
class Program
{
[DllImport(@"D:\...\AltRetTest.dll", CallingConvention=CallingConvention.StdCall)]
public static extern int MySub(int a, int b, [Out] int x, [Out] int y);
static void Main(string[] args)
{
int a = 4;
int b = 3;
int x = 0;
int y = 0;
MySub(a, b, x, y);
Console.WriteLine(x);
Console.WriteLine(y);
Console.WriteLine(MySub(a, b, x, y));
}
}
}
以下是我得到的答案: x = 0,y = 0,MySub(a,b,x,y)= 17
我在Visual C#编程方面有点新,但我认为上面的结果意味着这两个语句,即' a + b'和' 2 * a + 3 * b'已计算但未分配给x和y,后者(2 * a + 3 * b)已分配给函数MySub本身!我在C#中使用了OutAttributes,在FORTRAN中也使用了Intent [In],Intent [Out],但没有更改结果。我将不胜感激任何帮助或建议。
答案 0 :(得分:4)
和我一样,我认为INTENT(OUT)
意味着通过引用传递。但似乎并非如此。因此,您需要将以下内容添加到FORTRAN以强制通过引用传递:
!DEC$ ATTRIBUTES REFERENCE :: x,y
C#端函数的正确声明是:
[DllImport(...)]
public static extern void MySub(int a, int b, out int x, out int y);
这样称呼:
MySub(a, b, out x, out y)
请注意,您需要使用out
关键字,以便将指向输出变量的指针传递给本机代码。您需要使用out
或ref
来确保调用代码看到修改后的值。
另请注意,本机函数不返回值。巧合的是,返回值通过一个寄存器,该寄存器碰巧包含了最后一次执行计算的结果。