Почему у меня возникают проблемы при передаче аргумента в или из библиотеки Фортрана из VB.NET - PullRequest
1 голос
/ 01 февраля 2010

У меня есть DLL, написанная на фортране, которая, как я знаю, работает, потому что я получаю ее из рабочего программного пакета, который мы используем ежедневно. Я пытаюсь вызвать его из чего угодно, но у меня возникают проблемы с передачей правильно отформатированных аргументов в него и из него, поэтому я решил попробовать получить к нему доступ из программы VB. Я выбрал VB, потому что связался с разработчиком программного пакета, который мы используем, и он дал мне свой вызов функции DLL в VB6, хотя ему не разрешено показывать мне источник 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 ]

3 голосов
/ 01 февраля 2010

Я нашел решение. В VB6 аргумент, который не указан иначе, по умолчанию передается в функции как ByRef. В VB.NET, если вы оставляете аргумент пустым в объявлении функции, он автоматически вставляет ByVal, что, следовательно, является значением по умолчанию. VB.NET заставляет вас указывать другими словами, поэтому, если вы берете объявление функции из VB6 в VB.NET, знайте, что немаркированным значением по умолчанию в VB6 является ByRef.

1 голос
/ 01 февраля 2010

Да, типы данных VB.NET несовместимы с типами VB6. Целое число VB6 теперь шорт (иначе Int16). VB6 Long теперь является целым числом (он же Int32). VB6 Boolean был странной уткой, теперь эквивалентной Short, где значение True равно -1, а False равно 0.

Начните с изменения Long в объявлении функции на Integer, это Big.

0 голосов
/ 02 февраля 2010

Иногда необходимо использовать ключевое слово Auto во внешней функции со строковыми параметрами.

Declare Auto Sub FCC_Curves Lib...
...