【问题标题】:Making Fortran dll and calling it from C#制作 Fortran dll 并从 C# 调用它
【发布时间】:2012-04-25 14:22:35
【问题描述】:

我在 Fortran 可执行文件中有一个函数,我需要将其设为 dll 文件,以便可以从 C# 程序调用它的函数

      FUNCTION TSAT11(P) 
C     ** IGNORE IMPLEMENTATION **
      TSAT11 = SX*TSAT2(X) + SXL1*TSAT3-273.15 
      RETURN 
      END 

P 是一个浮点数,函数返回一个浮点数

这里我对fortran一无所知,也不从C#调用dll,所以请多解释一下。

我正在使用 Compaq Visual Fortran 和 C# 2008。

感谢您的宝贵时间。

(喜欢的可以看完整代码Here【这是一个计算水汽性质的程序】)

【问题讨论】:

  • 请说明P是如何定义的,以及函数返回的类型和数组维度。
  • 知道如何使用 Fortran 编译器制作 DLL 吗?
  • 整个 ** IGNORE IMPLEMENTATION ** 评论没有承认 Fortran/C 语言之间可能存在的多种调用约定差异。如果P 是一个字符,您必须承认隐藏长度参数等。
  • 我不使用返回值,而是使用out 参数。

标签: c# dll fortran


【解决方案1】:

这是一个使用单精度浮点数的示例。

Fortran 库包含:

FUNCTION TSAT11(P) 
!DEC$ ATTRIBUTES ALIAS:'TSAT11' :: TSAT11
!DEC$ ATTRIBUTES DLLEXPORT :: TSAT11
!DEC$ ATTRIBUTES VALUE :: P
REAL, INTENT(IN) :: P   
REAL :: TSAT11
    ! Examle calculation
    TSAT11 = P - 273.15
RETURN 
END FUNCTION

带有调用函数

class Program
{
    [DllImport("calc.dll")]
    static extern float TSAT11(float P);

    static void Main(string[] args)
    {
        float p = 300f;
        float t = TSAT11(p);
        // returns 26.8500061
    } 
 }

同样适用于数组(必须声明大小)

FUNCTION TSAT12(P,N) 
!DEC$ ATTRIBUTES ALIAS:'TSAT12' :: TSAT12
!DEC$ ATTRIBUTES DLLEXPORT :: TSAT12
!DEC$ ATTRIBUTES VALUE :: N
INTEGER, INTENT(IN) :: N
REAL, INTENT(IN) :: P(N)
REAL :: TSAT12
    ! Examle calculation
    TSAT12 = SQRT( DOT_PRODUCT(P,P) )
RETURN 
END FUNCTION

调用C#代码

class Program
{
    [DllImport("calc.dll")]
    static extern float TSAT12(float[] P, int N);

    static void Main(string[] args)
    {
        float[] p2=new float[] { 0.5f, 1.5f, 3.5f };
        float t2=TSAT12(p2, p2.Length);
        //returns 3.84057283
    } 
 }

【讨论】:

  • 谢谢你救了我的命,我明天有一个截止日期,你的答案就是我想要的一切。缺少一件事using System.Runtime.InteropServices;
  • @workoverflow - 我不得不说,有时 C# 函数需要 ref 到数组的第一个元素,而不是整个数组。喜欢TSAT12(ref p2[0]) 和声明static extern float TSAT12(ref float P, int N);
【解决方案2】:

您可以使用 P/Invoke。这是an article,它提供了一个示例。至于将 Fortran 代码编译成非托管 DLL,您可以在 CVF 中 create a DLL Project

【讨论】:

  • 考虑添加一个!DEC$ ATTRIBUTES VALUE :: P 装饰,避免使用ref 参数并按值传递。所以你用foo(p)代替foo(ref p)
猜你喜欢
  • 2019-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-03
相关资源
最近更新 更多