IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++/CLI Discussion :

Problème de passage d'entiers d'un code C# à une DLL native Delphi


Sujet :

C++/CLI

  1. #1
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2006
    Messages : 12
    Points : 10
    Points
    10
    Par défaut Problème de passage d'entiers d'un code C# à une DLL native Delphi
    Bonjour,

    je développe une appli Web ASP.Net en C# qui utilise une DLL win32 que je développe en Delphi.

    J'importe les fonctions de ma DLL avec P/Invoke :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
        [DllImport("Partner.dll")]
        public static extern void SetVal(double wVal);
        [DllImport("Partner.dll")]
        public static extern double GetVal();
        [DllImport("Partner.dll")]
        public static extern void CalculerPourcentagesDirects();
        [DllImport("Partner.dll")]
        public static extern double GetPourcentageDirect(int i, int j);
    Voici le code de ma DLL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    unit Calculs;
     
    interface
     
    uses SysUtils;
     
    procedure SetVal(wVal: double); export;
    function GetVal(): double; export;
     
    function MessageBox(HWnd: Integer; Text, Caption: PChar; Flags: Integer): Integer;
    stdcall; external 'user32.dll' name 'MessageBoxA';
     
    procedure CalculerPourcentagesDirects(); export;
    function GetPourcentageDirect(i, j: integer): double; export;
     
    implementation
     
    var
      Matrice: array of array of double;
      Val: double;
     
    procedure SetVal(wVal: double); export;
    begin
      Val:=wVal;
    end;
     
    function GetVal(): double; export;
    begin
      Result:=Val;
    end;
     
    procedure CalculerPourcentagesDirects(); export;
    var
      Dim, i, j: integer;
      Str: string;
    begin
      Dim := 5;
      SetLength(Matrice, Dim);
      for i:=0 to Dim-1 do begin
        SetLength(Matrice[i], Dim);
        for j:=0 to Dim-1 do
          Matrice[i,j]:=99.99;
      end;
    end;
     
    function GetPourcentageDirect(i, j: integer): double; export;
    var
      Resultat: double;
    begin
      MessageBox(0, PChar('Matrice['+IntToStr(i)+','+IntToStr(j)+']'), PChar('Matrice'), 0);
      Result := Matrice[i,j];
    end;
     
    end.
    Dans un premier temps je fais un essai avec les méthodes SetValue(val) et GetValue() pour vérifier que les paramètres de type double passent bien, ça marche.

    Puis je rempli une matrice de type double avec CalculerPourcentagesDirects() avant d'essayer de récupérer une valeur avec GetPourcentageDirect(i, j), et là ça marche pas.

    Pour déboguer ma DLL, j'affiche les entiers envoyés par mon code C# avec la fonction MessageBoxA(...) de la DLL user32.dll à partir de ma fonction GetPourcentageDirect(). Et là je vois que les entiers n'ont plus les même valeurs.

    A la première boucle, donc pour i et j = 0, du côté de la DLL je récupère i = 89969344 et j = 0, donc le code va chercher Matrice[89969344,0] et fait une violation d'accès.

    Voici la procédure C# qui fait appel aux fonctions de la DLL:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        public void RecupererPourcentages()
        {      
            try
            {
                SetVal(99.99);
                Sortie.Text += "<br>Val: " + GetVal().ToString();
     
                CalculerPourcentagesDirects();
                Sortie.Text += "<br><br>Matrice:<br>";
     
                for (int i = 0; i < 5; i++)
                {
                    Sortie.Text += "<br>";
                    for (int j = 0; j < 5; j++)
                    {
                        Sortie.Text += GetPourcentageDirect(i, j).ToString() + " ";
                    }
                }
            }
        }
    Et Sortie.Text :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Val: 99.99
     
    Matrice:
     
    System.AccessViolationException
    System.AccessViolationException: Tentative de lecture ou d'écriture de mémoire protégée.
    Cela indique souvent qu'une autre mémoire est endommagée.
    à _Default.GetPourcentageDirect(Int32 i, Int32 j) 
    à _Default.RecupererPourcentages() dans c:\Documents...\Default.aspx.cs:ligne 207
    J'ai également vérifié que la matrice est bien remplie dans la DLL avec MessageBoxA(...) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Matrice:
    99.99 99.99 99.99 99.99 99.99
    99.99 99.99 99.99 99.99 99.99
    99.99 99.99 99.99 99.99 99.99
    99.99 99.99 99.99 99.99 99.99
    99.99 99.99 99.99 99.99 99.99
    J'ai aussi testé la DLL à partir d'un code Delphi et ça fonctionne.

    Quelqu'un a t'il déjà rencontré ce problème sur le passage d'entiers ?
    Auriez-vous une piste ? D'autres choses à vérifier ?

    Merci

  2. #2
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2006
    Messages : 12
    Points : 10
    Points
    10
    Par défaut Types
    Pourtant les types win32/CLR correspondent bien :
    .NET: Calling Win32 DLLs in C# with P/Invoke

  3. #3
    Membre à l'essai
    Inscrit en
    Mars 2006
    Messages
    12
    Détails du profil
    Informations personnelles :
    Âge : 42

    Informations forums :
    Inscription : Mars 2006
    Messages : 12
    Points : 10
    Points
    10
    Par défaut Trouvé ^^
    Citation Envoyé par swirtel
    Je rajoute que la seule possibilité actuellement d'utiliser des DLL à travers différents langages est de respecter le types primitifs en stdcall.

    Attention, Delphi comme C++ Builder emploient du fastcall qui est un passage de paramètres sur trois registres, c encore un truc à la sauce borland
    (http://www.developpez.net/forums/sho...d.php?t=225279)

    Effectivement, il faut mettre la convention d'appel "stdcall" dans la déclaration des procédures et fonctions pour que le passage des paramètres soit compatible avec les languages extérieurs (genre C# avec .Net).

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 34
    Dernier message: 27/08/2012, 13h01
  2. Réponses: 4
    Dernier message: 11/10/2011, 14h34
  3. Problème de passage d'un tableau de caractère vers un DLL en C
    Par philipina dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 22/02/2008, 08h36
  4. DLL Native chargeant et appelant du code dans une DLL.NET
    Par cinemania dans le forum C++/CLI
    Réponses: 3
    Dernier message: 17/04/2007, 07h12
  5. Problème lors de l'import d'une dll native.
    Par -Jolan- dans le forum C++/CLI
    Réponses: 4
    Dernier message: 21/02/2007, 12h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo