Prb avec dll et tableau dynamique

bd - 11 déc. 2001 à 09:11
 Philippe Gormand - 14 déc. 2001 à 09:10
actuellement je recois en parametre d'une fonction un tableau de longueur variable. ce tableau est rempli dans la fonction de la dll.
au retour dans la procedure je recupère bien toutes les données mais le processus bloque pour cause de trop nombreuses erreurs d'exeption.

8 réponses

Philippe Gormand
11 déc. 2001 à 10:47
Salut. Quelles erreurs exactement ?
As tu pensé à mesurer la longueur du tableau reçu, et à
allouer la bonne longueur au tableau de réception avec cette valeur ?
0
-------------------------------
Réponse au message :
-------------------------------

Salut. Quelles erreurs exactement ?
As tu pensé à mesurer la longueur du tableau reçu, et à
allouer la bonne longueur au tableau de réception avec cette valeur ?


-------------------------------
Réponse au message :
-------------------------------

actuellement je recois en parametre d'une fonction un tableau de longueur variable. ce tableau est rempli dans la fonction de la dll.
au retour dans la procedure je recupère bien toutes les données mais le processus bloque pour cause de trop nombreuses erreurs d'exeption.
0
-------------------------------
Réponse au message :
-------------------------------
peut on passer en parametre un tableau de longueur variable
l'application envoie 2 variables (Pchar) et reçoit en retour un tableau (array of pchar) construit dans la dll
après essai l'opération s'effectue correctement mais la sortie de la procédure appelante provoque le message suivant
(opération sur pointeur invalide)

-------------------------------
Réponse au message :
-------------------------------

Salut. Quelles erreurs exactement ?
As tu pensé à mesurer la longueur du tableau reçu, et à
allouer la bonne longueur au tableau de réception avec cette valeur ?


-------------------------------
Réponse au message :
-------------------------------

actuellement je recois en parametre d'une fonction un tableau de longueur variable. ce tableau est rempli dans la fonction de la dll.
au retour dans la procedure je recupère bien toutes les données mais le processus bloque pour cause de trop nombreuses erreurs d'exeption.
0
Philippe Gormand
12 déc. 2001 à 12:54
Bon. Alors, oui on peut passer en paramètre à une fonction ou une procedure, un tableau de longueur variable ( depuis DELPHI 4 ).
Typiquement , la syntaxe est la suivante :

Function MaFonction(Tableau : Array Of Integer) : Boolean;

Si c'est la fonction qui retourne un array of PChar, c'est un tableau de pointeurs. Il faudrat donc déclarer la fonction de type pointer.
La déclaration est la suivante :
Type
PTableau = array of PChar;
Tableau = Function(C1, C2 : PChar) : PTableau;

Var
Retour : Tableau;
begin
....
@Retour:=Tableau(......

J'avou que je connais mal les pointeurs de fonction.

Mais pour les tableau ouvert et tableau dynamique ( c'est pas tout à fait la meme chose ) dans l'aide de delphi, le sujet est bien documenté.

Donnes moi le code, ça cera plus facile, parceque là...
A+

Au fait http://philippe.gormand.free.fr/
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
j'ai effectivement put passer mon tableau dynamique en paramètre. ce que j'ai trouvé c'est qu'il faut ajouter
SHAREMEM dans la DLL et le programme appelant. Pour une question de partage mémoire.
cela permet de supprimer l'erreur de pointeur en fin d'execution de la procedure TForm1.Button3Click
par contre cette erreur d'exeption apparait à la fermeture de l'application???

voila le code

Pgr DLL

unit MsproCenturaU1;

interface

uses ShareMem, DBTables, DB, Classes, SysUtils;

Type
TyTab = record
Valeur: Double;
Flag:boolean;
end;
TyDates = array[1..2] of Pchar;
TyGlobal = record
dates:TyDates;
Tab:array of TyTab;
end;
PGlobal = TyGlobal;

function ChoixDateReference(D1,D2:Pchar):Pchar;

implementation

function ChoixDateReference(D1,D2:Pchar):Pchar;
var paquet:PGlobal;
begin
paquet.dates[1]:=D1;
paquet.dates[2]:=D2;
SetLength(Paquet.Tab,3);
Paquet.Tab[0].Valeur:=321;
Paquet.Tab[1].Valeur:=654;
Paquet.Tab[2].Valeur:=987;
Paquet.Tab[0].Flag:=true;
Paquet.Tab[1].Flag:=false;
Paquet.Tab[2].Flag:=true;
//ChoixDateReference:=paquet;
ChoixDateReference:=D1;
end;

prg appelant :

avec PGlobal de la meme structure que dans la DLL

procedure TForm1.Button3Click(Sender: TObject);
var i:integer;
V:PGlobal;
D1,D2:pchar;
begin
D1:=Pchar(Edit4.Text);
D2:=PChar(Edit5.Text);
V:=ChoixDateRefence(D1,D2);
ListBox1.Clear;
ListBox1.Items.Add(V.Dates[1]);
ListBox1.Items.Add(V.Dates[2]);
i:=0;
while (i<length(V.Tab)) do
begin
ListBox1.Items.Add(FormatFloat('##.##',V.Tab[i].Valeur));
if V.Tab[i].Flag
then ListBox1.Items.Add('*')
else ListBox1.Items.Add('//') ;
i:=i+1;
end;
i:=0;

end;

si tu as une idée elle sera la bienvenue
A+
0
Philippe Gormand
13 déc. 2001 à 13:22
Bon aparament, l'erreur était facile à trouver.
Je ne le répéterai jammais assez, il faut souvent compulser l'aide en ligne de DELPHI, qui est la meilleur de tous les outils de développement confondus.
Il est bien expliqué dans l'aide sur l'utilisation des tableaux dynamiques, que se sont des pointeurs.
Donc si ont alloue de la mémoire à un tableau dynamique
( SetLength(MonTableau,50) ), il faut le libérer après usage comme on libère un pointeur -> MonTableau:=Nil;

Dans ta fonction ChoixDatereference, tu fais bien une allocation mémoire avec SetLength(Paquet.Tab,3) mais tu ne libères pas le tableau. Paquet.Tab:=Nil

Dans ta fonction, ecrit :
ChoixDateReference:=D1;
Paquet.Tab:=Nil;
End;

ou

Result:=D1;
Paquet.Tab:=Nil;
End;

Bon. Je crane un peu, mais c'est surement le problème. Mais attention, on a souvent des surprises avec les pointeurs, et leur usage peut dépendre de leur déclaration, Local ou global, d'autant qu'avec les versions de DELPHI 4 et plus, toutes les variables locales sont gérée comme des pointeurs, mais c'est tranparent pour le programmeur. Pour dire que quelque fois, ont a des surprises...

A +
0
bon quelques modifs plue tard...
j'ai quelque peu modifier le source (voir ******)
et j'ai bien mis les modifs selon ton conseil.
par contre je me suis aperçu que le simple fait de lancer le prg puis de le fermer suffisait pour me générer l'erreur
donc je n'ai même pas appeler la DLL....

nouveau source

Pgr DLL

unit MsproCenturaU1;

interface

uses ShareMem, DBTables, DB, Classes, SysUtils;

Type
TyTab = record
Valeur: Double;
Flag:boolean;
end;
TyDates = array[1..2] of Pchar;
TyGlobal = record
dates:TyDates;
Tab:array of TyTab;
end;
PGlobal = TyGlobal;

function ChoixDateReference(D1,D2:Pchar):PGlobal; ******

implementation

function ChoixDateReference(D1,D2:Pchar):PGlobal; ******
var paquet:PGlobal;
begin
paquet.dates[1]:=D1;
paquet.dates[2]:=D2;
SetLength(Paquet.Tab,3);
Paquet.Tab[0].Valeur:=321;
Paquet.Tab[1].Valeur:=654;
Paquet.Tab[2].Valeur:=987;
Paquet.Tab[0].Flag:=true;
Paquet.Tab[1].Flag:=false;
Paquet.Tab[2].Flag:=true;
ChoixDateReference:=paquet; ******
Paquet.Tab:=nil; ******
end;

prg appelant :

avec PGlobal de la meme structure que dans la DLL

procedure TForm1.Button3Click(Sender: TObject);
var i:integer;
V:PGlobal;
D1,D2:pchar;
begin
D1:=Pchar(Edit4.Text);
D2:=PChar(Edit5.Text);
V:=ChoixDateRefence(D1,D2);
ListBox1.Clear;
ListBox1.Items.Add(V.Dates[1]);
ListBox1.Items.Add(V.Dates[2]);
i:=0;
while (i<length(V.Tab)) do
begin
ListBox1.Items.Add(FormatFloat('##.##',V.Tab[i].Valeur));
if V.Tab[i].Flag
then ListBox1.Items.Add('*')
else ListBox1.Items.Add('//') ;
i:=i+1;
end;
i:=0;
V.Tab:=nil; ******
end;
0
Philippe Gormand
14 déc. 2001 à 09:10
Attention : Si une fonction d'une DLL est utilisée ( chargée ) en static, la partie de code executable de la fonction est chargée en mémoire, dès l'exécution du programme...
0
Rejoignez-nous