从 C# 调用 FORTRAN dll 并将值分配给结构数组 [英] Calling FORTRAN dll from C# and assigning values to array of structures

查看:18
本文介绍了从 C# 调用 FORTRAN dll 并将值分配给结构数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以将 C# 结构传递到 FORTRAN 就好了.我什至可以在 FORTRAN 中将 C# 结构的数组作为 TYPE() 的数组传递.我遇到麻烦的地方是当我试图将值返回到 C# 时.下面是一个例子:

I can pass a C# struct into FORTRAN just fine. I can even pass an array of a C# struct as an array of TYPE() in FORTRAN. Where I run into trouble is when I tried to return values back into C#. Here is an example:

fortran dll 是:

The fortran dll is:

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

和期望结果的C#调用函数是:

and the C# calling function that expects results is:

[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 实例中.

Debugging through the FORTRAN code, I see the initial values pass from C# to FORTRAN just fine. The the values get overridden with new values and control is passed back into C# where the old values are still contained within the ValueRef instances.

为什么我可以以类似的方式传递和返回 floatint 的数组,就好了.我可以传递和返回带有 ref 关键字的单数结构,我可以传递但不能返回和 struct 的数组?

Why is it that I can pass and return an array of float, or int in a similar fashion, just fine. and I can pass and return singular structures with ref keyword, and I can pass but not return and array of struct?

PS.我正在使用 Compaq Visual Fortran 6.5 &.NET 3.5
PS2.我感谢对此的任何评论/想法.我的项目已经完成了 95%,现在我遇到了这个问题.这个项目的重点是尽可能多地使用结构来减少传递给函数的参数#of并保留OOP设计的某些方面.

PS. I am using Compaq Visual Fortran 6.5 & .NET 3.5
PS2. I appreciate any comments/ideas on this. I am 95% done with my project, and now I run into this issue. The whole point of this project is to use structures as much as possible to reduce the #of arguments passed to functions and retain certain aspects of OOP design.

推荐答案

我过去使用指针而不是数组来完成此操作.我认为正在为 P/Invoke 调用复制您的结构:

I have done this in the past using a pointer, not an array. I think that your structures are being copied for the P/Invoke call:

[DllImport("mathlib.dll")]
static extern void TEST_REF(ValueRef* t, int n);

在调用该方法之前,您需要固定数组.

You will need to pin your array before calling the method.

fixed (ValueRef* pointer = t)
{
  TEST_REF(pointer, n);
}

根据评论,解决方案是将外部声明为

Based on the comments the solution is to declare the external as

[DllImport("mathlib.dll")]
static extern void TEST_REF([Out] ValueRef[] t, int n);

这是一个 MSDN关于数组编组的参考,以及它们如何默认[In].

Here is a MSDN reference on Marshaling of arrays, and how they default to [In].

这篇关于从 C# 调用 FORTRAN dll 并将值分配给结构数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆