【问题标题】:Using Fortran DLL in VB在 VB 中使用 Fortran DLL
【发布时间】:2012-12-17 15:17:05
【问题描述】:

我正在尝试自学从 VB 调用 fortran 子程序。我正在尝试使用非常简单的示例,但不知何故它不起作用。我正在使用带有 Intel Visual Fortran 的 Visual Studio 2010。这是我正在尝试的代码:

SUBROUTINE ARRAYTEST(arr)
!DEC$ ATTRIBUTES DLLEXPORT, ALIAS:"ARRAYTEST" :: ARRAYTEST
REAL arr(3, 7)
INTEGER i, j
DO i = 1, 3
    DO j = 1, 7
        arr (i, j) = 11.0 * i + j
    END DO
END DO
END SUBROUTINE

并成功构建以创建 DLL 文件。这是我的 Visual Basic 代码:

Public Class Form1
Private Declare Sub ARRAYTEST Lib "FortTest.DLL" Alias "ARRAYTEST" (ByVal x As Single)
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    Dim arr(0 To 2, 0 To 6) As Single
    Call ARRAYTEST(arr(0, 0))
    TextBox1.Text = arr(3, 3)
End Sub

End Class

 当我把DLL文件放到目录下,运行代码时,出现如下错误: ForRun.exe 中发生了“System.AccessViolationException”类型的第一次机会异常

我用谷歌搜索但没有找到解决方案,如果有人能告诉我我做错了什么以及如何解决它,我将不胜感激。非常感谢您。

【问题讨论】:

  • 从未使用过fortran,但显然sub 需要一个指向real 的指针,而您传递了一个实际的real,它被解释为指针。尝试声明 x() As Single 并编组为 LPArray: Private Declare Sub ARRAYTEST Lib "FortTest.DLL" Alias "ARRAYTEST" (<MarshalAs(UnmanagedType.LPArray), [In](), Out()> ByVal x() As Single)

标签: vb.net dll fortran


【解决方案1】:

您可以尝试DllImport 表示法,这是我在这个特定场景中最成功的方法(来自 VB.NET 的 FORTRAN)。

Imports System.Runtime.InteropServices

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim arr(0 To 2, 0 To 6) As Single
        ARRAYTEST(arr(0, 0))
        TextBox1.Text = arr(3, 3)
    End Sub

End Class

Public Module FortranInterop
    <DllImport("FortTest.DLL", CallingConvention:=CallingConvention.StdCall, EntryPoint:="ARRAYTEST")> _
    Public Sub ArrayTest(ByRef x as Single)
    End Sub    
End Module
  1. 我要提到的第一件事是传递数组时需要传递变量ByReference。我很确定我们通过引用传递了所有变量,但我不确定如果 FORTRAN 没有修改它是否有必要。这可能是您的 AccessViolation 错误的来源。

  2. 其次,我设置了 StdCall CallingConvention,但我不能 100% 确定 IVF 中的默认调用约定是什么。我们总是在属性头中明确地将其设置为CDECL

  3. 最后,我会谨慎地将 2D(+) 数组传递给 FORTRAN。我认为我没有实际测试过或看过它,但我在 IVF 开发人员论坛上读到 FORTRAN 转置了从 .NET 传递的数组(行变成列)。还有一点需要注意。

【讨论】:

    【解决方案2】:

    我知道这是一个老问题,但似乎没有人注意到一个简单的答案。您已经声明了 arr(0 To 2, 0 To 6),但是您调用的 arr(3,3) 超出了声明的范围(3 不包含在 0 To 2 中)。 System.AccessViolationException 是一个常见错误,通常表明您已在数组边界之外引用,即您试图访问内存中尚未为此变量保留的内容,因此访问冲突。

    如果你使用了 TextBox1.Text = arr(2,3),你不应该得到那个错误,整个事情应该可以正常工作。

    希望这对现在正在查看该问题的任何人有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      • 2012-08-16
      • 1970-01-01
      • 2012-05-10
      • 1970-01-01
      • 2018-09-03
      相关资源
      最近更新 更多