我正在尝试自学从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基本代码:
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'类型的第一次机会异常我用谷歌搜索但没有找到解决方案,我真的很感激,如果有人能告诉我我做错了什么以及如何解决它。非常感谢你。
答案 0 :(得分: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
我要提到的第一件事是传递数组时传递变量ByReference
是必要的。我很确定我们通过引用传递所有变量,但我不确定如果FORTRAN没有修改它是必要的。这可能是您的AccessViolation错误的来源。
其次,我提出了StdCall CallingConvention,但我不能100%确定IVF中的默认调用约定。我们始终在属性标题中明确将其设置为CDECL
。
最后,我会谨慎地将2D(+)数组传递给FORTRAN。我不认为我实际上已经测试或看过它,但我在IVF开发人员论坛上读到FORTRAN转换从.NET传递的数组(行成为列)。另一件需要注意的事情。
答案 1 :(得分:1)
我知道这是一个老问题,但有一个简单的答案似乎没有人注意到。你已经声明了arr(0到2,0到6),但是你正在调用arr(3,3),它超出你声明的范围(3不包含在0到2中)。 System.AccessViolationException是一个常见错误,通常表示您已在数组的边界外引用,即您正在尝试访问内存中尚未为此变量保留的内容,因此访问冲突。
如果您使用TextBox1.Text = arr(2,3),则不应该出现该错误,整个过程应该可以正常工作。
希望现在可以帮助任何人查看这个问题。