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:
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:
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:
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:
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:
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 :mrgreen: