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

API, COM et SDKs Delphi Discussion :

Probleme appel fonction objet COM


Sujet :

API, COM et SDKs Delphi

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Par défaut Probleme appel fonction objet COM
    Bnjouro

    J'ai 2 erreur qui se produise lorsque je fais appel à des fonctions de mon objet COM :

    J'ai une première erreur m'indiquant que CoInitialize n'a pas été appelé donc j'ai rajouté CoInitialize(nil) avant mon appel de fonction malgr le fait que j'ai le code

    initialization
    CoInitialize(nil);

    dans mon unité .

    Et maintenant j'ai l'erreur suivante ;
    L'application a appelé une interface qui était maintenue en ordre pour une thread différente.

    Auriez-vous une idée du problème.

    Le but de cet objet COM est de partagé un contexte de fonctionnement entre plusieurs appli. Je n'ai bien sur pas les sources de cet objet.

    Merci

  2. #2
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 081
    Par défaut
    Partager un contexte entre plusieurs threads d'un même processus, oui c'est faisable ! Déjà il faut jouer avec du ClassInstancing et du ThreadingModel (dans le code de l'objet)

    Partager un contexte entre plusieurs processus, ça me semble fort délicat, ... est-ce au moins possible ???
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Par défaut
    A priori, j'ai une exemple en VB qui utilise cet objet COM et cela fonctionne en lançant plusieurs fois l'appli VB.
    Le problème est vraiment lié à l'utilisation de l'objet COM.

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 081
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 081
    Par défaut
    On ne peut pas t'aider plus sans connaitre cet objet COM,

    Pourquoi ne pas utiliser CreateFileForMapping\MapViewOfFile pour créer des zones mémoires partageables, c'est standard au système windows et cela ne nécessite pas l'utilisation d'un composant tiers ...
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre confirmé
    Inscrit en
    Février 2003
    Messages
    138
    Détails du profil
    Informations forums :
    Inscription : Février 2003
    Messages : 138
    Par défaut
    J'ai enfin trouvé, j'ai fait la bétise d'appeler les propriétés de l'objet com au sein d'un httpservercommandget (composant idhttp).
    Or il semble que les composants Indy travaillent ans un thread différent du thread de l'appli principal et donc l'objet COM n'est plus défini dans le thread idhttp.
    Il suffit de faire un timer et de le faire declencher par la procédure servercommandget pour que la procédure s'execute dans le thread principal et que tout fonctionne.

    Tordu et pas très joli mais bon

  6. #6
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    Citation Envoyé par dd16 Voir le message
    Bnjouro

    J'ai 2 erreur qui se produise lorsque je fais appel à des fonctions de mon objet COM :

    J'ai une première erreur m'indiquant que CoInitialize n'a pas été appelé donc j'ai rajouté CoInitialize(nil) avant mon appel de fonction malgr le fait que j'ai le code

    initialization
    CoInitialize(nil);

    dans mon unité .

    Et maintenant j'ai l'erreur suivante ;
    L'application a appelé une interface qui était maintenue en ordre pour une thread différente.

    Auriez-vous une idée du problème.

    Le but de cet objet COM est de partagé un contexte de fonctionnement entre plusieurs appli. Je n'ai bien sur pas les sources de cet objet.

    Merci
    je suis tombé sur ce problème récemment en jouant sur le multithreading.

    et j'ai trouvé une solution

    voici ce que ça donne :
    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
     
    type
      TMyThread = class(TThread)
      private
       FStream : IStream;
       FMonObjet : IMonObjet;
      public
       constructor Create(AMonObjet: IMonObjet);
       procedure Execute; override;
      end;
     
    constructor TMyThread.Create(AMonObjet : IMonObjet);
    begin
    // marshalling de l'objet dans un IStream
      CoMarshalInterThreadInterfaceInStream(IMonObjet, AMonObjet, FStream);
    // lancer le thread (non suspendu)
      inherited Create(False);
    end;
     
    procedure TMyThread.Execute;
    begin
      CoInitialize(nil);
    // depuis le thread, on récupère l'objet marshallé :)
      CoGetInterfaceAndReleaseStream(FStream, IMonObjet, FMonObjet);
    // attention ! FStream ne doit pas être libéré par Delphi !
    // on force sa valeur à nil en transtypant pour que Delphi n'invoque pas Release.
      pointer(FStream) := nil;
    // maintenant on peut utiliser FMonObjet sans problème
     ...
    end;
    Par contre je rencontre un autre problème

    Si dans un Syncrhonize() de mon Thread je fais appel à l'interface de mon thread principal je tombe sur une erreur "An outgoing call cannot be made since the application is dispatching an input-synchronous call.". Et ça c'est très chiant !

    exemple :

    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
     
    type
      TMyThread = class(TThread)
      private
       FStream : IStream;
       FMonObjet : IMonObjet;
      public
       constructor Create(AMonObjet: IMonObjet);
       procedure Execute; override;
       procedure MainThread;
      end;
     
    procedure TMyThread.Execute;
    begin
    // ... voir ci-dessus ...
      Synchronize(MainThread);
    end;
     
    procedure TMyThread.MainThread;
    begin
      Form1.FMonObjet.MaMethode; // -> bing j'ai l'erreur !
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  7. #7
    Expert éminent
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Par défaut
    bon j'ai compris mon problème c'est Delphi 5 !

    la méthode Synchronize de Delphi 5 utilise un SendMessage vers le thread principal, à partir de Delphi 7 je pense, c'est un Event qui est utilisé.

    Voici une version simplifiée du mécanisme :

    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
    55
    56
    57
    58
    59
    60
    61
    62
     
    type
      TSyncRecord = record
        Event  : THandle;
        Method : TThreadMethod;
      end;
     
    var
      gLock : TRTLCriticalSection; // doit être initilisé avec InitializeCriticalSection
      gList : TList = nil;
     
    procedure MySynchronize(AMethod: TThreadMethod);
    var
      cSyncRecord : TSyncRecord;
    begin
      if GetCurrentThreadID = MainThreadID then
        AMethod
      else
      begin
        cSyncRecord.Event := CreateEvent(nil, True, False, '');
        cSyncRecord.Method := AMethod;
        EnterCriticalSection(gLock);
        try
          if not Assigned(gList) then
            gList := TList.Create;
          gList.Add(@cSyncRecord);
        finally
          LeaveCriticalSection(gLock);
        end;
       // force Application.OnIdle qui doit invoquer ExcuteSynchronizeProcs
        PostMessage(Application.Handle, WM_NULL,0, 0);
        WaitForSingleObject(cSyncRecord.Event, INFINITE);
        CloseHandle(cSyncRecord.Event);
      end;
    end;
     
    // doit être invoqué périodiquement...par exemple sur Application.OnIdle
    function ExcuteSynchronizeProcs: Boolean;
    var
      cList : TList;
      i : Integer;
    begin
      EnterCriticalSection(gLock);
      try
        cList := gList;
        gList := nil;
      finally
        LeaveCriticalSection(gLock);
      end;
      Result := Assigned(cList) and (cList.Count > 0);
      if not Result then
        Exit;
      for i := 0 to Pred(cList.Count) do
      begin
        with TSyncRecord(cList[i]^) do
        begin
          Method;
          SetEvent(Event);
        end;
      end;
      cList.Free;
    end;
    Ceci dit, je recontre un nouveau problème que je n'ai pas encore identifié...pour mes tests je fais un ShowMessage('...') dans ma procédure synchronisée qui a été invoquée via le OnIdle...et là, de temps en temps, mon, appli se gèle...
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

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

Discussions similaires

  1. Probleme appel fonction de lib .so
    Par L4BiN dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 07/01/2011, 13h55
  2. [FLASH 8] Probleme appel fonction
    Par jbidou88 dans le forum Flash
    Réponses: 2
    Dernier message: 20/03/2007, 15h28
  3. [RPC] Appels distants : remplacer des objets COM
    Par pataguillon dans le forum C++
    Réponses: 26
    Dernier message: 30/03/2006, 09h17
  4. [VB.Net] Problème appel fonction par un bouton
    Par balibo dans le forum ASP.NET
    Réponses: 4
    Dernier message: 25/11/2005, 10h48
  5. [MFC] débutant probleme appel de fonction
    Par Gloubi99 dans le forum MFC
    Réponses: 9
    Dernier message: 30/08/2005, 15h40

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