【问题标题】:Using a Fortran dll with C# and character arrays将 Fortran dll 与 C# 和字符数组一起使用
【发布时间】:2016-03-15 23:26:16
【问题描述】:

我正在尝试在 C# 中使用 Fortran DLL,但我没有使用 Fortran 的经验。我遇到问题的部分是 dll 的输出参数,特别是字符。在 Fortran 代码中,它们被定义为:

character*32 JobName
character*(*)  Fname
character*80  Title(2)

有人知道 C# 中的等价物吗?所有其他都是整数,所以我可以处理它们。通过阅读,我不能直接使用 char,因为它在 C# 中是 8 个字节,在 Fortran 中是 4 个字节。

更多 Fortran 代码如下:

*deck,ResRdBegin
    function ResRdBegin (Nunit, Lunit, Fname, ncFname, Title, JobName, Units, NumDOF, DOF, UserCode, MaxNode, NumNode, MaxElem, NumElem, MaxResultSet,NumResultSet)
    integer ResRdBegin, Nunit, Lunit, ncFname, Units, iTemp(100), NumDOF, DOF(*), UserCode, kbf, NumResultSet, MaxNode, NumNode, MaxElem, NumElem, MaxResultSet, i,j
    character*32 JobName
    character*(*)  Fname
    character*80  Title(2)

【问题讨论】:

  • 您是想将其转换为 C#,还是实际引用 DLL?我不确定您是否可以引用 Fortran DLL,除非它包含在 COM 中。
  • this question 的回答涵盖了两种情况。 character*(*) 的形式给出了一个假定的长度字符变量,其行为与其他两个略有不同。
  • 请注意,只有最后一个是一个数组(长度为 2),其他只是字符串,而不是数组。更重要的是参数列表中可能有隐藏参数:stackoverflow.com/questions/34822683/…stackoverflow.com/questions/8207997/…隐藏参数包含字符串的长度,而不是数组的长度。
  • 要说得更多,你就必须播种更多。至少是 Fortran 过程的完整标头。包括任何编译器指令。
  • 谢谢大家,有很多东西要通读...这需要我一点时间。同时,我将添加更多细节。我有点含糊,因为源代码受版权保护,但我获得了使用 dll 的许可。该文件用于从某些商业软件读取二进制输出。这是一个博客文章的链接,其中有人使用 cpp 做了同样的事情。同样,我在处理字符类型时遇到了问题。 padtinc.com/blog/the-focus/…

标签: c# dll fortran character


【解决方案1】:

您应该能够在 C# 中使用 char[](与 CharSet.Ansi)将字符数组传递给 Fortran。对于 2x80 字符数组,我只需传入一个 160 字符数组。 character*(*) 变量的长度通过 ncFname 参数定义为输入。使用 [In,Out] 指定数组参数的输入和输出。标量应该通过 ref 传递。

http://www.luckingtechnotes.com/calling-fortran-dll-from-csharp/

P/Invoke 签名应如下所示。

[DllImport("binlib.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int RESRDBEGIN(ref int Nunit, ref int Lunit, [In] char[] Fname, ref int ncFname, [In, Out] char[] Title, [In, Out] char[] JobName,
     ref int Units, ref int NumDOF, [In, Out] int[] DOF, ref int UserCode,
     ref int MaxNode, ref int NumNode, ref int MaxElem, ref int NumElem,
     ref int MaxResultSet, ref int NumResultSet);

我也运行 ANSYS。我测试过,这种方法似乎有效 - 返回有效数据。但是,如果您在调用之前设置断点,调试器会抛出 AccessViolation,所以我可能会遗漏一些东西。如果在调用之后设置断点,则没有问题。

【讨论】:

  • 谢谢,我现在可以正常工作了……还有其他一些问题。 VS默认更喜欢32位,dll是64位。该 dll 引用了许多其他 dll。如果程序崩溃,它似乎会锁定对文件的访问。感谢您的所有帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-07
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多