Erreur fatale de compilation [Résolu]

Signaler
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
-
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
-
Bonjour,
lorsque je compile ou construit mon soft, delphi indique "erreur interne L594". sur la FAQ, l'erreur interne L signifie "Linker". Dois je m'en inquiéter ? Est-ce que ça vous parle ?
merci
Seb

12 réponses

Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
oui tu peu en effet mettre le tableau en statique si le nombre d'element ne depasse pas une certaine limite fixe.

de toute façon je ne vois aucune erreur la dedans ... peut etre utilise tu un thread ? auquel cas on peu en effet avoir des probleme si on essaye d'ajuster la taille du tableau tout en le lisant d'un autre coté.

vus que ton enregistrement fait 76 octets ... tu peu meme si tu veux faire un array[0..99] of TSite. (760 octets)

quand je pense que j'ai fait des tableaux dynamique beaucoup plus lourd que ça ...

petit conseil, tu pourrait faire comme cela :

TMatrix10B = array[0..9] of boolean;
TMatrix4i     = array[0..3] of integer;

TSite = record
    Drawing : boolean;
    RR,RRO : TRect;
    Center : TPoint;
    Bond : TMatrix10B;
    MonSite : String;
    TypeRelais : TMatrix4i;
    Numero : integer;
end;

TCC = Array of TSite;

procedure AddSite(var CC: TCC; const Site : TSite);
begin
    SetLength(CC, Length(CC)+1);
    CC[High(CC)] := Site;
end;

en sachant que l'indice de CC vas de 0 a N

evite, si tu l'a fait de faire :

CC[Length(CC)-1] car si length = 0 tu vas chercher l'indice -1 donc ... probleme

et toujours faire quelque controls preliminaire comme :

if Length(CC) = 0 then exit;

tu peu egalement te faire une Classe et placer TSite en TCollectionItem ... ça demande un peu plus de code mais au final l'utilisation est hyper simplifiée et securisée.
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
je viens d'identifier la ligne qui semble causer cette erreur de compilation :
setlength(cc,(length(cc)+1));
cc est un tableau dynamique. je ne vois pas où le bas blesse .
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
mmm ... je pense que l'erreur viens de plus haut que cette ligne ...

car si :

CC = array of Type;

la ligne

 SetLength(CC, Length(CC) + 1);

ne devrais pas provoquer d'erreur.

regarde plutot si tu n'a pas une declaration puante d'une directive $L ou $LINK

sinon pourrait t'on avoir plus de code pour t'aider ... au moins la source de l'unité qui semble provoquer l'erreur ?
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
Quand je mets cette ligne en commentaire, je n'ai plus le message d'erreur.c'est pour ça que je pense que celle ci est la cause du message.
concernant le code, je ne sais pas quoi mettre. pour info, CC est un tableau de données de type record.
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
comment est declaré ton tableau ?
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
CC : array of TSite;
...
procedure TForm1.FormCreate(Sender: TObject);
begin
....
SetLength(cc,1);
....
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
ok ... quand tu auras finis de donner les infos au compte goutes ... ^^

array of TSite ça m'avance pas ... je me doute bien que c'est un Array of ...

c'est la structure du record et le code qui viens avant SetLength(CC,x) qui m'interresse
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
type TSite = record
drawing : boolean; // en cours de déplacement
rr : trect; // rectangle position courante
rro : trect; // ancien ancienne position
centre : Tpoint;
bond : array[1..10] of boolean ;
nom_site : string;
type_relais : array[1..4] of integer;
numero : integer;
end;

SetLength(CC,x) vient après le click sur un bouton confirmant la création d'une image sur une carte. je ne sais pas quoi t'indiquer de plus.
mon appli : je place des triangles (polyline) sur une carte (paintbox).cc[x] correspond à un triangle. je crée un tableau de CC que j'initialise sur le formcreate.puis j'incrémente la taille de cc[] à chaque fois que l'on rajoutera un triangle sur la carte.
le nombre maxi de triangles sur la carte ne devrait pas dépasser 20, je pourrais peut être me passer d'un tableau dynamique et utiliser un statique.
Seb
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
merci pour toutes ces infos & conseils.je débutes en programmation et tout ceci m'intéresse car mon but est de faire du "code" dont "l'utilisation est hyper simplifiée et securisée.."
je pars donc avec un tableau statique.
peux tu m'en dire plus sur les classes ? je regardes du côté de ce tutoriel :
http://sjrd.developpez.com/delphi/delphitutoriels/composants/graphiques/?page=collections
Messages postés
4202
Date d'inscription
samedi 16 octobre 2004
Statut
Modérateur
Dernière intervention
13 juin 2020
37
aller je suis de bonne humeur aujourd'hui et comme je sais que l'elaboration d'une classe est une chose peu evidente au debut je te donne la classe TSitesManager complete...

libre a toi ensuite de chercher a ajouter des evenements, methodes, propriétés ect... ect...

recopis tout cela dans une unité vierge et enregistre la dans le repertoire LIB de delphi.
ensuite installe ce nouveau composant que tu trouveras dans l'onglet "Exemple".

place le sur ta fiche et hop ... tu n'a plus qu'a ecrire ton programme avec la classe TSitesManager qui gereras tout pour toi.

Remarque que les evenements sont facile a créer, un evenements se decompose de la maniere suivante :

interface
type
   { type procedure of object qui permet de determiné une procedure type }
   TNamedEvent = procedure(Sender : TObject [;Arguments]) of object;

   TClasse = class
   private
     { la variable qui pointeras sur le gestionnaire d'evenement }
     fOnNamedEvent : TNamedEvent;
   protected
     { le caller, permet d'appeler l'evenement a l'interieur de la classe
       doit etre virtual pour permettre la derivation de la methode }
     procedure NamedEventQuery([Arguments]); virtual;
   published
     { la propriété qui s'afficherat dans l'onglet evenement de l'inspecteur d'objet }
     property OnNamedEvent : TNamedEvent read fOnNamedEvent write fOnNamedEvent;
   public
   end;

implementation

procedure TClasse.NamedEventQuery([Arguments]);
begin
  { on doit appeler l'evenement uniquement si un gestionnaire y est attaché,
    c'est une convention unique qui doit etre absoluement respectée.
    il est interdit d'appeler un gestionnaire de remplacement si aucun
    gestionnaire n'est associé. il ne faut pas non plus declancher d'exceptions
    si c'est le cas. L'utilisateur doit etre libre de declarer un gestionnaire
    ou non. }
  if Assigned(fOnNamedEvent) then
     fOnNamedEvent(Self [,Arguments]);
end;

et on appeleras NamedEventQuery dans la methode qui doit declancher l'evenement.
simple non ?
Il existe un type d'evenement predefinie qui se nome TNotifyEvent. c'est une evenement simple qui ne retourne que le Sender (Self) de l'evenement.
Mais il existe egalement d'autre type d'evenements ... pas besoin de les cités tous.


<hr size="2" width="100%" />



unit SitesMan;

INTERFACE

uses Windows, SysUtils, Classes, Types;

type
   TMatrix10B = array[0..9] of boolean;
   TMatrix4i  = array[0..3] of integer;

   { forwarding des classes, declarer des classes pas encore definient pour pouvoir
     y acceder a partir de classes declarée plus haut dans l'unité }
   TSitesCollection  = class;
   TSitesManager     = class;

{ TSiteItem ---------------------------------------------------------------------------------- }
   { TSiteItem correspond a l'ancien type record TSite, il ne contient que les données et
     quelques routine de gestion }

   TSiteItem = class(TCollectionItem)
   private
     fCollection   : TSitesCollection;
     fDrawing      : boolean;
     fRR           : TRect;
     fRRO          : TRect;
     fCenter       : TPoint;
     fBond         : TMatrix10B;
     fMonSite      : String;
     fTypeRelais   : TMatrix4i;
     fNumero       : integer;
     procedure SetDrawing(val : boolean);
     procedure SetRect(index : integer; val : TRect);
     procedure SetPoint(val : tpoint);
     procedure SetBond(index : integer; val : Boolean);
     function GetBond(index : integer) : boolean;
     procedure SetString(val : string);
     procedure SetRelais(index : integer; val : integer);
     function GetRelais(index : integer) : integer;
     procedure SetInt(val : integer);
   protected
     function GetDisplayName : string; override;
    published
     property MonSite    : String         read fMonSite    write SetString;
     property Numero     : integer        read fNumero     write SetInt;
   public
     property Drawing    : boolean        read fDrawing    write SetDrawing;
     property RR         : TRect  index 0 read fRR         write SetRect;
     property RRO        : TRect  index 1 read fRRO        write SetRect;
     property Center     : TPoint         read fCenter     write SetPoint;
     property Bond       [index : integer] : boolean  read GetBond   write SetBond;
     property TypeRelais [index : integer] : integer  read GetRelais write SetRelais;

     procedure MakeBond(const Args : array of boolean);
     procedure MakeTypeRelais(const Args : array of integer);

     constructor Create(Collection : TCollection); override;
     procedure Assign(Source : TPersistent); override;
   end;

{ TSitesCollection ------------------------------------------------------------------------ }
  { TSitesCollection correspond a l'ancien tableau dynamique array of TSite
    c'est lui qui a la lourde charge de gerer la creation/liberation des TSiteItem,
    il ne sert qu'a cela }

  TSitesCollection = class(TCollection)
  private
    fSitesManager : TSitesManager;
    function GetItem(Index: Integer): TSiteItem;
    procedure SetItem(Index: Integer; Value: TSiteItem);
  protected
    function GetOwner: TPersistent; override;
  public
    constructor Create(SitesManager: TSitesManager);
    function Add : TSiteItem;
    property Items[Index: Integer]: TSiteItem read GetItem write SetItem; default;
  end;

{ TSitesManager --------------------------------------------------------------------------- }
  { TSiteManager correspond aux anciennes routines externe utlisées dans le programme pour
    traiter les données de TSite et le tableau array of TSite. C'est lui qui vas donc
    jouer le chef d'orchestre entre les items et la collection. }

   TSitesManager = class(TComponent)
   private
     fSitesCollection : TSitesCollection;
     procedure SetSites(Val : TSitesCollection);
     procedure SetItem(index : integer; val : TSiteItem);
     function  GetItem(index : integer) : TSiteItem;
   protected
   published
     property Sites : TSitesCollection read fSitesCollection write SetSites;
   public
     property Items[index : integer] : TSiteItem read GetItem write SetItem;
     function Add(const Item : TSiteItem) : integer;
     procedure Delete(const index : integer);
     function Count : integer;

     constructor Create(AOwner : TComponent); override;
     destructor Destroy; override;
   end;

{ enregistrement du composant dans la palette }
procedure Register;

IMPLEMENTATION

procedure Register;
begin
  RegisterComponents(
     'Exemples',  { on definit la palette ou l'on vas installer le composant }
     [TSitesManager]); { le nom de la classe du composant a installer }
end;

{ comparaison de deux variable TPoint }
function ComparePoint(const P1,P2 : TPoint) : boolean;
begin  result :(P1.X P2.X) and (P1.Y = P2.Y);
end;

{ comparaison de deux variable TRect }
function CompareRect(const R1,R2 : TRect) : boolean;
begin  result :(r1.Left   r2.Left) and
            (r1.Top    = r2.Top) and
            (r1.Right  = r2.Right) and
            (r1.Bottom = r2.Bottom);
end;

{ TSiteItem ------------------------------------------------------------------------------- }
constructor TSiteItem.Create(Collection: TCollection);
var N : integer;
begin
  fCollection := (Collection as TSitesCollection);
  fDrawing      := false;
  fRR           := Rect(0,0,0,0);
  fRRO          := Rect(0,0,0,0);
  fCenter       := Point(0,0);
  fMonSite      := 'unnamed';
  Self.MakeBond([False]);
  Self.MakeTypeRelais([0]);
  fNumero       := fCollection.Count;
  inherited Create(Collection);
end;

{ permet d'afficher une information descriptive de l'item dans l'inspecteur d'objet }
function TSiteItem.GetDisplayName: string;
begin
  Result := format('Site %d : %s',[fNumero,fMonSite]);
end;

procedure TSiteItem.SetDrawing(val : boolean);
begin
  if fDrawing <> Val then begin
     fDrawing := Val;
     Changed(false);
  end;
end;

procedure TSiteItem.SetRect(index : integer; val : TRect);
begin
  case index of
   0 : if not CompareRect(fRR,Val) then begin
           fRR := Val;
           Changed(false);
       end;
   1 : if not CompareRect(fRRO,Val) then begin
          fRRO := Val;
          Changed(false);
       end;
  end;
end;

procedure TSiteItem.SetPoint(val : tpoint);
begin
  if not ComparePoint(fCenter,Val) then begin
     fCenter := Val;
     Changed(false);
  end;
end;

procedure TSiteItem.SetBond(index : integer; val : boolean);
begin
  if (index >= 0) and (index <= 9) then
     if fBond[index] <> Val then begin
        fBond[index] := Val;
        Changed(false);
     end;
end;

function TSiteItem.GetBond(index : integer) : boolean;
begin
  result := fBond[index]
end;

procedure TSiteItem.SetString(val : string);
begin
  if fMonSite <> Val then begin
     fMonSite := Val;
     Changed(false);
  end;
end;

procedure TSiteItem.SetRelais(index : integer; val : integer);
begin
  if (index >= 0) and (index <= 3) then
     if fTypeRelais[index] <> Val then begin
        fTypeRelais[index] := Val;
        Changed(false);
     end;
end;

function TSiteItem.GetRelais(index : integer) : integer;
begin
  result := fTypeRelais[index];
end;

procedure TSiteItem.SetInt(val : integer);
begin
  if fNumero <> Val then begin
     fNumero := Val;
     Changed(false);
  end;
end;

procedure TSiteItem.Assign(Source : TPersistent);
begin
  if source is TSiteItem then begin
     with TSiteItem(Source) do begin
        Self.fDrawing     := Drawing;
        Self.fRR          := RR;
        Self.fRRO         := RRO;
        Self.fCenter      := Center;
        Self.fBond        := fBond;
        Self.fMonSite     := MonSite;
        Self.fTypeRelais  := fTypeRelais;
        Self.fNumero      := Numero;
     end;
  end else
     inherited Assign(source);
end;

{ Crée un tableau a partir des arguments on peu placer 1 ou 9 arguments
  1 seul argument, le tableau est remplit avec cette valeur.
  9 arguments, le tableau est remplit dans l'ordre avec les 9 valeurs }
procedure TSiteItem.MakeBond(const Args : array of boolean);
var N : integer;
begin
  if length(Args) = 9 then
     for N := 0 to 9 do
         fBond[N] := Args[N]
  else
  if length(Args) = 1 then
     for N := 0 to 9 do
         fBond[N] := Args[0];
end;

{ fonctionnement identique a MakeBond ... sauf qu'ici nous auront 1 ou 4 arguments }
procedure TSiteItem.MakeTypeRelais(const Args : array of integer);
var N : integer;
begin
  if length(Args) = 4 then
     for N := 0 to 3 do
         fTypeRelais[N] := Args[N]
  else
  if length(Args) = 1 then
     for N := 0 to 3 do
         fTypeRelais[N] := Args[0]
  else
     for N := 0 to 3 do
         fTypeRelais[N] := 0;
end;

{ TSitesCollection ------------------------------------------------------------------------ }

constructor TSitesCollection.Create(SitesManager : TSitesManager);
begin
  fSitesManager := SitesManager;
  inherited Create(TSiteItem);
end;

function TSitesCollection.GetItem(Index: Integer): TSiteItem;
begin
  Result := TSiteItem(inherited GetItem(Index));
end;

procedure TSitesCollection.SetItem(Index: Integer; Value: TSiteItem);
begin
  inherited SetItem(Index, Value);
end;

function TSitesCollection.GetOwner: TPersistent;
begin
  Result := fSitesManager;
end;

function TSitesCollection.Add : TSiteItem;
begin
  Result := (inherited Add) as TSiteItem;
end;

{ TSitesManager --------------------------------------------------------------------------- }

constructor TSitesManager.Create(AOwner : TComponent);
begin
  inherited Create(AOwner);
  fSitesCollection := TSitesCollection.Create(Self);
end;

destructor TSitesManager.Destroy;
begin
  fSitesCollection.Free;
  inherited Destroy;
end;

procedure TSitesManager.SetSites(Val : TSitesCollection);
begin
  fSitesCollection.Assign(Val);
end;

procedure TSitesManager.SetItem(index : integer; val : TSiteItem);
begin
  fSitesCollection.SetItem(index,val);
end;

function  TSitesManager.GetItem(index : integer) : TSiteItem;
begin
  result := fSitesCollection.GetItem(index);
end;

{ crée un item et renvois son index dans la collection }
function TSitesManager.Add(const Item : TSiteItem) : integer;
begin
  with fSitesCollection.Add do begin
       Assign(item);
       result := index;
  end;
end;

procedure TSitesManager.Delete(const index : integer);
begin
  fSitesCollection.Delete(index);
end;

function TSitesManager.Count : integer;
begin
  result := fSitesCollection.Count;
end;

end.







<hr size="2" width="100%" />
Messages postés
3825
Date d'inscription
vendredi 23 juillet 2004
Statut
Modérateur
Dernière intervention
1 février 2021
40
Salut,

pour revenir à ton problème de départ (après le code de F0xi c'est pas évident )

type TSite = record
       drawing : boolean;   // en cours de déplacement
       rr  : trect;         // rectangle position courante
       rro : trect;         // ancien ancienne position
       centre : Tpoint;
       bond : array[1..10] of boolean ;
       nom_site : string[80];  // Une erreur se produit si aucune limite n'est donné à un String
       type_relais : array[1..4] of integer;
       numero : integer;
     end;
Var cc : Arrayof TSite;
procedure TForm1.Button11Click(Sender: TObject);
begin
SetLength(CC,1);
With cc[0] do
Begin
drawing : = True;
rr  := Rect(0,0,100,100);
rro := Rect(100,100,500,500);
centre := Point(200,200);
bond[1] := True;
nom_site := 'DelphiFr';
type_relais[1] := 2;
numero := 15;
End;
End;

Ce code a été testé et il fonctionne
Bien sur la méthode de F0xi est bien plus propre mais c'était juste pour comprendre le pourquoi du comment

@+
Cirec
Messages postés
51
Date d'inscription
lundi 13 juin 2005
Statut
Membre
Dernière intervention
25 juillet 2006
1
Salut Cirec, j'ai limité la taille des strings mais l'erreur se produit toujours.
Salut f0xi, merci d'avoir pris le temps pour ajouter cette réponse. je vais travailler dessus pour comprendre et l'utiliser correctement. je posterai de nouveaux sujets lorsque je rencontrerai des difficultés de compréhension
Seb