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

Langage Delphi Discussion :

Passage de paramètres à un jvThread


Sujet :

Langage Delphi

  1. #1
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 157
    Points : 1 414
    Points
    1 414
    Par défaut Passage de paramètres à un jvThread
    Bonjour a tous

    Voici un problème que je n'arrive pas à résoudre surtout parce qu'il n'est pas systématique

    La semaine dernière, cela fonctionnait, mais depuis cette semaine, ça plante (et rien n'a été changé dans cette partie du programme).

    Voici la description du problème (sous D2010)

    Je lance l'exécution d'un Thread (venant de chez JEDI soit TJvThread) en y associant un pointer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    jv_Extract.Execute(@Info);
    Ce pointeur fait "référence" à un record dont voici la structure :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
       tExtraction = RECORD
            Fichier_Out: STRING;
            Localisation_Fille: boolean;
            Taxon_Fille: boolean;
            Confidentialite: boolean;
            Destination: TStringList;
            Liste_Requete: TStringList;
            Tableau: tTab_Extern;
        END;
    Je récupère les infos dans le "Execute" du Thread avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CopyMemory(@Infos, Params, sizeof(tExtraction));
    A l'appel de la procédure, toutes les informations contenues dans le RECORD (info) sont correct.
    Mais à l'entrée de la procédure, le RECORD (Infos) lui est vide.


    des idées ??

    je rappelle que la semaine dernière cela fonctionnait


    merci d'avance
    olivier

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 736
    Points : 25 645
    Points
    25 645
    Par défaut
    Je t'explique ma méthode pour le TThread de base !

    Tu créés un constructeur prenant en paramètre un const tExtraction (pas de pointeur)

    Dans le constructeur, tu copie ce tExtraction dans un membre privé !
    tu peux utiliser une simple affectation et non un Copymemory (cela devrait mieux gérer la copie de la string)
    Pour les TStringList, tu devrais carrement les recopier intégralement elle aussi, idem pour les autres objets !

    Dans le Execute, tu peux travailler sur cette copie sans soucis !

    Une variante !
    TExtraction devient une classe TExtractionObj
    Tu ajoutes des Accesseurs et des Sections Critiques dedans !
    Tu créés un constructeur prenant en paramètre un TExtractionObj, c'est la référence !
    tu la stocke dans un membre privé!
    Dans Execute, tu peux travailler en te rappelant que c'est le même objet, les Sections Critiques ou TMultiReadWriteSync étant là pour sécuriser les accès !

    Le Mode Copie ou le Mode Partagée, est selon ton besoin !


    Pour le TJvThread, cela doit être assez proche, à la seule différence qu'il semble que tu puisse passer un pointeur à l'équivalent d'un Resume !

    Pense aussi que tu copie juste la mémoire du tExtraction
    Fichier_Out étant une chaine, c'est un pointeur, je l'avoue, je ne sais pas ce que cela fait, est-ce que la chaine est partagée ? ou Delphi arrive quand même à bidouiller un compteur de référence, bon je ne fais JAMAIS de CopyMemoryavec des AnsiStringmais uniquement ShortStringou Array[0..n] of Char.

    Idem, tes TStringList, tu ne fais copier que le pointeur, tu n'as aucune protection contre l'accès concurrentiel ou pire une libération !

    Est-ce la bonne Doc : TJvThread.Execute
    Si oui, Jedi est encore plus mal documenté que Delphi, c'est dingue !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CopyMemory(@Infos, Params, sizeof(tExtraction));
    Params est-il le P de la Doc ?
    Infos est-il une variable locale de Execute (membre privé de l'objet ?)
    Tu as peut-être un conflit, tu pense modifier un membre alors que tu modifie une variable locale ?
    TExtraction est déclaré dans une seule unité (pas de conflit à ce sujet, ça arrive, j'ai tendance à créer des types très longs avec des prefixe comme le fait Jedi avec Jv, TMS avec adv comme celui que j'ai créé cette après-midi : TShaiCameraAbstractViewScreen ou IShaiCameraEntityPurposeDelphiInterface, comme je suis en C++, je précise l'utilisation d'une Delphi Interface qui est un type différent des pseudo-interfaces C++)

    sizeof(tExtraction) ça fait combien ?
    20 en supposant que tTab_Extern est un tableau dynamique donc un pointeur !

    Le Record en Delphi 2010 peut avoir des bidouilles pour ressembler à un objet !
    Cela peut-il nuire au sizeof qui renverrait 4 comme si c'était une classe ?
    un mot clé comme packed pourrait éviter cela (ce qui au passage renverra 19 au lieu de 20)

  3. #3
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 157
    Points : 1 414
    Points
    1 414
    Par défaut
    Bonjour ShaiLeTroll

    désolé pour le retard de ma réponse

    J'ai toujours un peu de mal avec les Threads, d'où leurs utilisations avec des trucs et astuces que je trouve sur le forum (merci le forum). Et il faudra que je m'y plonge très sérieusement un de ces jours.

    Est-ce la bonne Doc : TJvThread.Execute
    Oui, c'est en effet bien juste

    En tout cas, tu m'as mis sur la voie avec un mot, merci

    C'est le mot "privée" qui m'a fait penser au niveau de "privatisation" de ma variable "Info" (type RECORD).

    Dans la procédure qui lance l’exécution du THREAD, la variable Info est Locale. Il en est de même dans l’exécution du THREAD ou la variable (Infos) qui reçoit le paramètres est également locale.

    Le problème est tout bêtement que le temps que le passage de paramètres se fasse vers le THREAD, la procédure qui lance le THREAD est terminée, et donc les variables libérées. Donc toutes les données stockées dans "Info" n'existent plus lorsque le copyMemory est exécuté...

    Pour corriger cela, j'ai créé un variable public (un BOOLEAN) qui termine si le passage de données a eu lieu, et j'utilise cette variable pour empêcher la procédure d'appel du THREAD de se terminer. et bongo !


    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
    Procedure AppelThread;
    Var
       info : tExtraction; // le record 
    Begin
        ....
        ....
       Info.1 := 45541;
       .....
     
       Charge_Infos := False;  // Variable globale qui gere le passage du paramètre "Info"
       jv_Thread.Execute((@Info);
       REPEAT
              Sleep(50);   // pour eviter de sortir de cette procédure avant que le passage du paramètre soit effectué
       UNTIL (Charge_Infos);
    End;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Procedure jv_ThreadExecute(Sender: TObject; Params: Pointer);
    Var
       infos : tExtraction; // le record 
    Begin
            CopyMemory(@Infos, Params, sizeof(tExtraction));
            info_charge := True;
           ....
           ...
      // et c'est parti :)
     
    End;

    donc merci ShaiLeTroll
    olivier

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 736
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 736
    Points : 25 645
    Points
    25 645
    Par défaut
    Ah le Execute(P: Pointer) c'est directement le lancement en thread, je pensais que c'était encore un code non threadé d'initialisation puis une fois ce code effectué, cela provoquait la mise en route du thread !

    Bon, je t'ai mis sur la piste de la durée de vie de la variable locale et tu as résolu ton problème, c'est le plus important !

    Pense cliquer sur

    HS :
    Sur ma remarque que TExtraction était un identifiant un peu court, eh bien, je me suis fait avoir par le contraire du conflit de nommage !

    Citation Envoyé par ShaiLeTroll Voir le message
    ...j'ai tendance à créer des types très longs avec des prefixe comme le fait Jedi avec Jv, TMS avec adv comme celui que j'ai créé cette après-midi : TShaiCameraAbstractViewScreen ou IShaiCameraEntityPurposeDelphiInterface, comme ...
    Dans le genre long, j'ai pondu ce matin TShaiDVRDahuaTechnology_DH_DVR0404LE_LinkedCameraConfiguratorForm.
    Oui très long et trop même !
    Découverte importante, je ne le savais pas mais le nom d'une classe de fenêtre est limité à 63 caractères Dommage, j'ai dépassé de peu !
    L'arroseur arrosé !

  5. #5
    Membre expérimenté
    Homme Profil pro
    Ingenieur de recherche - Ecologue
    Inscrit en
    Juin 2003
    Messages
    1 157
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingenieur de recherche - Ecologue

    Informations forums :
    Inscription : Juin 2003
    Messages : 1 157
    Points : 1 414
    Points
    1 414
    Par défaut
    Je met le résolu


    Également, je met des préfixes

    merci encore

  6. #6
    Membre éprouvé
    Avatar de CapJack
    Homme Profil pro
    Prof, développeur amateur vaguement éclairé...
    Inscrit en
    Mars 2004
    Messages
    624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Prof, développeur amateur vaguement éclairé...
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2004
    Messages : 624
    Points : 988
    Points
    988
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Dans le genre long, j'ai pondu ce matin TShaiDVRDahuaTechnology_DH_DVR0404LE_LinkedCameraConfiguratorForm.
    Oui très long et trop même !
    Découverte importante, je ne le savais pas mais le nom d'une classe de fenêtre est limité à 63 caractères Dommage, j'ai dépassé de peu !
    Il faudra y penser au moment de la création de TShaiDVRDahuaTechnology_DH_DVR0404LE_LinkedCameraConfiguratorForm2.

    Je ne suis déjà plus là...

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    32
    Détails du profil
    Informations personnelles :
    Âge : 54
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 32
    Points : 19
    Points
    19
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Découverte importante, je ne le savais pas mais le nom d'une classe de fenêtre est limité à 63 caractères Dommage, j'ai dépassé de peu !
    L'arroseur arrosé !
    Ca me rappelle il y a une dizaine ... euh non, 'tain déjà 20 ans ... je m'étais fait piéger avec 2 variables globales de 36 caractères qui se différenciaient par les 2 derniers caractères.

    Le compilo n'a pas râlé, n'a considéré que les 32 premiers caractères et a en quelque sorte mergé mes 2 variables. J'étais à l'école et je me souviens avoir galéré pour trouver pourquoi mon programme ne marchait pas ...

    Je suis depuis ce temps là beaucoup moins verbeux.

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

Discussions similaires

  1. [Forms]Passage de paramètre entre Forms et Reports
    Par jack554 dans le forum Reports
    Réponses: 4
    Dernier message: 30/03/2004, 14h58
  2. probleme lors du passage de paramètre
    Par maxmj dans le forum ASP
    Réponses: 4
    Dernier message: 18/11/2003, 01h15
  3. [XSL] Passage de paramètres à un template
    Par pantin dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 27/06/2003, 14h28
  4. passage de paramètres
    Par pram dans le forum XMLRAD
    Réponses: 5
    Dernier message: 18/02/2003, 18h28
  5. passage en paramètre d'un array dynamique 2D
    Par Guigui_ dans le forum Langage
    Réponses: 4
    Dernier message: 27/11/2002, 20h47

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