1

我正在尝试自学从 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”类型的第一次机会异常

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

4

2 回答 2

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 传递的数组(行变成列)。只是另一件需要注意的事情。

于 2012-12-17T15:47:21.917 回答
1

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

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

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

于 2014-05-09T02:38:16.847 回答