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