为什么我在从VB.NET向FORTRAN DLL传递参数时遇到问题

时间:2010-02-01 15:19:24

标签: vb.net dll vb6 fortran vb6-migration

我有一个用fortran编写的DLL我知道可行,因为我从一个我们日常使用的工作软件包中获取它。我试图从任何东西调用它,但我有问题我相信通过正确格式化的参数进出它,所以我决定尝试从VB程序访问它。我之所以选择VB,是因为我联系了我们正在使用的软件包的开发人员,他在VB6中给了我他的DLL函数调用,即使他不允许向我展示FORTRAN源代码。

问题是(或许,我认为)我在VB.NET中编写,它具有与VB6不同的数据类型。谁能明白为什么我遇到了问题。

运行时出现的错误是:“AccessViolationException未处理:尝试读取或写入受保护的内存。这通常表示其他内存已损坏。”

这是我提供的函数调用:

Declare Sub FCC_Curves Lib "FCC_Curves.dll" (Read_Flag As Boolean, First_Flag As Boolean, Frequency_MHz As Single, IQT As Integer,  ByVal Radiation_Opt As String, ByVal L1 As Long,  ERP_Watts As Single, T_PowerWatts As Single, Tx_GaindBi As Single, T_Loss As Single, ByVal Service As String, ByVal L2 As Long, Reliability As Integer, ByVal FCC_CurvesDataPath As String, ByVal L3 As Long,  ByVal TerrainRoughness As String, ByVal L4 As Long, Haatm As Single, NPRfl As Integer, NFCCCurve As Integer, HPRfl As Single,  Crve As Single, FCC_Loss As Single, Code As Integer, FS As Single)

这是我的代码:

Module Module1

    Declare Sub FCC_Curves Lib "FCC_Curves.dll" (ByVal Read_Flag As Boolean, ByVal First_Flag As Boolean, ByVal Frequency_MHz As Single, ByVal IQT As Int16, ByVal Radiation_Opt As String, ByVal L1 As Int32, ByVal ERP_Watts As Single, ByVal T_PowerWatts As Single, ByVal Tx_GaindBi As Single, ByVal T_Loss As Single, ByVal Service As String, ByVal L2 As Int32, ByVal Reliability As Int16, ByVal FCC_CurvesDataPath As String, ByVal L3 As Int32, ByVal TerrainRoughness As String, ByVal L4 As Int32, ByVal Haatm As Single, ByVal NPRfl As Int16, ByVal NFCCCurve As Int16, ByVal HPRfl() As Single, ByVal Crve() As Single, ByRef FCC_Loss As Single, ByRef Code As Int16, ByRef FS() As Single)


    Sub Main()

        Dim Read_Flag As Boolean
        Dim First_Flag As Boolean
        Dim Frequency_MHz As Single
        Dim IQT As Int16
        Dim Radiation_Opt As String
        Dim L1 As Int32
        Dim ERP_Watts As Single
        Dim T_PowerWatts As Single
        Dim Tx_GaindBi As Single
        Dim T_Loss As Single
        Dim Service As String
        Dim L2 As Int32
        Dim Reliability As Int16
        Dim FCC_CurvesDataPath As String
        Dim L3 As Int32
        Dim TerrainRoughness As String
        Dim L4 As Int32
        Dim Haatm As Single
        Dim NPRfl As Int16
        Dim NFCCCurve As Int16
        Dim HPRfl(12) As Single
        Dim Crve(5) As Single
        Dim FCC_Loss As Single
        Dim Code As Int16
        Dim FS(15) As Single
        'Dim HPRfl As Single
        'Dim Crve As Single
        'Dim FCC_Loss As Single
        'Dim Code As Int16
        'Dim FS As Single

        Read_Flag = True
        First_Flag = True
        Frequency_MHz = 98.1
        IQT = 0
        Radiation_Opt = "ERP"
        L1 = 3
        ERP_Watts = 1000
        T_PowerWatts = 1000
        Tx_GaindBi = 2.15
        T_Loss = 0
        Service = "Broadcast"
        L2 = 9
        Reliability = 50
        FCC_CurvesDataPath = "C:\Program Files\CSPT_Extension\data\"
        L3 = 37
        TerrainRoughness = "Off"
        L4 = 3
        Haatm = 1500
        NPRfl = 13
        NFCCCurve = 6
        Dim i As Int16
        HPRfl(0) = 11
        HPRfl(1) = 128
        For i = 2 To 12
            HPRfl(i) = 1500
        Next
        For i = 0 To 5
            Crve(i) = i * 15
        Next



        FCC_Curves(Read_Flag, First_Flag, Frequency_MHz, IQT, Radiation_Opt, L1, ERP_Watts, T_PowerWatts, Tx_GaindBi, T_Loss, Service, L2, Reliability, FCC_CurvesDataPath, L3, TerrainRoughness, L4, Haatm, NPRfl, NFCCCurve, HPRfl, Crve, FCC_Loss, Code, FS)

    End Sub

End Module

3 个答案:

答案 0 :(得分:3)

我找到了解决方案。在VB6中,默认情况下,未以其他方式指定的参数作为ByRef传递给函数。在VB.NET中,如果在函数声明中将参数留空,它会自动插入ByVal,因此它似乎是默认的事实。 VB.NET强制你指定,换句话说,如果你从VB6到VB.NET的函数声明,知道VB6中未标记的默认值是ByRef。

答案 1 :(得分:1)

是的,VB.NET数据类型与VB6数据类型不兼容。 VB6 Integer现在是Short(又名Int16)。 VB6 Long现在是一个Integer(又名Int32)。 VB6布尔值是一个奇怪的鸭子,现在相当于Short,其中值True为-1,False为0。

首先将函数声明中的Long更改为Integer,即Big One。

答案 2 :(得分:0)

有时需要在带有字符串参数的外部函数中使用Auto关键字。

Declare Auto Sub FCC_Curves Lib...