2017-08-22 3 views
1

J'essaie de lier une bibliothèque de liens dynamiques Fortran (DLL) avec une application VB.NET. La sous-routine contenue dans la DLL est censée modifier une valeur c fournie du côté VB, mais elle ne le fait pas: elle conserve c telle quelle.Pourquoi cette DLL Fortran n'est-elle pas lue par mon application VB.NET?

Voici le code Fortran:

SUBROUTINE prueba_int(m,n,p) 
!DEC$ ATTRIBUTES DLLEXPORT, DECORATE, ALIAS : "prueba_int" :: prueba_int 
!DEC$ ATTRIBUTES REFERENCE :: m,n 
IMPLICIT NONE 
INTEGER, INTENT(IN) :: m,n 
INTEGER,INTENT(OUT) :: p 

p=m*n 

END SUBROUTINE 

Et voici la section VB.NET:

Public Class Form1 
Public Declare Sub prueba_int Lib "Dll2.dll path" (ByRef m As Integer, ByRef n As Integer, ByRef p As Integer) 
Private Sub btn1_Click(sender As Object, e As EventArgs) Handles btn1.Click 
    ofd.Filter = "(*txt)|*.txt" 
    If (ofd.ShowDialog() = DialogResult.OK) Then 
     txtArray.Text = ofd.FileName 
    End If 
End Sub 

Private Sub btnCalc_Click(sender As Object, e As EventArgs) Handles btnCalc.Click 
    Dim a, b, c As Integer 
    a = CInt(txt1.Text) 
    b = CInt(txt2.Text) 
    c = 1 
    Call prueba_int(a, b, c) 
    MsgBox(c) 'Only to check c's value 
End Sub 
End Class 

Je l'ai déjà essayé d'utiliser LONG au lieu de INTEGER, mais le problème est resté. Quelqu'un peut-il me donner une idée de ce problème?

EDIT: Les codes VB.NET et FORTRAN ont tous deux été programmés à l'aide de Visual Studio 2015 avec le compilateur Intel Fortran (Parallel XE 2017). La DLL a été créée à l'aide de la convention d'appel STDCALL(/iface:stdcall).

+0

Je ne suis pas grand sur Fortran, alors prenez ce que je dis avec un grain de sel ... mais vous avez m et n marqué comme IN et p marqué comme OUT. Mais dans le vb ils sont tous déclarés ByRef. J'aurais pensé que m et n devraient être ByVal et seulement p serait ByRef. –

+0

Merci d'avoir répondu @ErikWestwig! J'utilisais justement 'ByVal' avec' m' et 'n', mais si je le fais, l'exception' System.AccessViolationException' apparaît, accompagnée d'un avertissement pour essayer d'écraser la mémoire protégée. Utiliser 'ByRef' sur eux était le seul moyen de l'éviter. – MSalmer

+0

Je pense que vous devez déclarer 'p' comme INTENT (INOUT) si vous voulez changer la valeur de c. –

Répondre