AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi COM Objekte in Threads. Wie geht das richtig ?
Thema durchsuchen
Ansicht
Themen-Optionen

COM Objekte in Threads. Wie geht das richtig ?

Ein Thema von jensw_2000 · begonnen am 4. Jan 2006 · letzter Beitrag vom 4. Jan 2006
Antwort Antwort
jensw_2000
(Gast)

n/a Beiträge
 
#1

COM Objekte in Threads. Wie geht das richtig ?

  Alt 4. Jan 2006, 13:28
Ich versuche grade ein älteres Projekt komplett auf CoKlassen umzustellen. Die CoClasses sollen zusätzlich noch in Threads verwendet werden. Datei habe mich von Alzaimars Thread-Job Beispiel insprieren lassen.

Zurzeit kämpfe ich damit, die COM-Objekte in den Threads direkt anzusprechen (anstatt importierte Klassen zu verwenden), jedoch erhalte beim Hinzufügen von Jobs zur Jobliste immer folgende Fehlermeldung :

Zitat:
Eine Schnittstelle, die für einen anderen Thread marshalled war, wurde von der Anwendung aufgerufen.
Ich habe beim Googeln jemanden gefunden der das gleiche Problem hatte, jedoch verstehe ich nicht, warum der Fehler bei mir auftritt.

In dem Newsgroup-Artikel kann ich das Problem nachvollziehen, weil im Hauptthread ein COM Objekt erzeugt wird, auf das mehrere Threads zugreifen.

Bei mir hat jeder "Workerthread" eine eigene Instanz des COM-Objektes. Somit sollte es doch keine Kollisionen geben oder ?


Das Thread-Objekt ...
Delphi-Quellcode:
  TWorkerThread = class(TThread)
  private
    fID: Integer;
    fCallObj: DIVASDKLIB_TLB.IDivaCall;
    fDivaCallEvents: TDIVASDKLibIDivaCallEvents;
    procedure DoExecuteJob(ajob: TJob);
    procedure DivaCallEventsConnected(Sender: TObject);
    procedure DivaCallEventsDisconnected(Sender: TObject);
    procedure DivaCallEventsToneReceived(Sender: TObject; cTone: Byte);
  protected
    constructor Create(aID: Integer);
    destructor Destroy;
    procedure Execute; override;
  end; //TWorkerThread
...

Delphi-Quellcode:
constructor TWorkerThread.Create(aID: Integer);
begin

  CoInitialize(nil);

  inherited Create(True);
  fID := aID;

  // Instanz von IDivaCall erzeugen und konfigurieren
  fCallObj := InstObj.CreateCall as DIVASDKLIB_TLB.IDivaCall;
  fCallObj.SignalEvents := -1;
  fCallObj.AsyncMode := 0; // -1;
  fCallObj.EnableDigitDetection := -1;
  fCallObj.EnableExtendedToneDetection := -1;
  fCallObj.VoiceEnableEchoCanceler := -1;
  fCallObj.LocalNumber:='0815';

  // Event-Wrapper Objekt erzeugen und verbinden (EventSink)
  fDivaCallEvents := TDIVASDKLibIDivaCallEvents.Create(nil);
  fDivaCallEvents.Connect(fCallObj);

  // Ereignisbehandlungsroutinen zuweisen
  fDivaCallEvents.OnConnected := DivaCallEventsConnected;
  fDivaCallEvents.OnDisconnected := DivaCallEventsDisconnected;
  fDivaCallEvents.OnToneReceived := DivaCallEventsToneReceived;

  Resume;
end;

destructor TWorkerThread.Destroy;
begin
 fDivaCallEvents.Disconnect;
 fDivaCallEvents.Free;
 fCallObj:=nil;
 CoUninitialize;
 inherited destroy;
end

procedure TWorkerThread.DoExecuteJob(ajob: TJob);
begin

  if aJob = nil then exit;

  // Showmessage(inttostr(fCallObj.Callstate));

  LogM(form1.log, GetCallResultCodesS(fCallObj.Connect(aJob.Rufnummer, DivaCallType_Voice)));

end;
Wenn Jobs zur Jobliste hinzugefügt werden wird TWorkerThread.DoExecuteJob aufgerufen. Sobald ich dort versuche auf fCallObj zuzugreifen, erscheint die o.a. Fehlermeldung (einmal pro Thread der einen Job übernimmt). Im Debugger kann man am Pointer von "fCallObj" sehen, das fCallObj in jedem Thread auf eine eigene Instanz von IDivaCall verweist.

Für Vorschläge (oder bessere Lösungen) bin ich dankbar. Im Moment steckt ich etwas fest.

Das SDK ist kostenlos.
Die importierte Typenbibliothek und die Event-Implementation (von EventSink) hänge ich mit in die Anlage.


Danke und schöne Grüße,
Jens

Angehängte Dateien
Dateityp: pas divasdklib_tlb_195.pas (112,4 KB, 5x aufgerufen)
Dateityp: pas divasdklibevents_915.pas (35,5 KB, 8x aufgerufen)
  Mit Zitat antworten Zitat
Benutzerbild von Bernhard Geyer
Bernhard Geyer

Registriert seit: 13. Aug 2002
17.171 Beiträge
 
Delphi 10.4 Sydney
 
#2

Re: COM Objekte in Threads. Wie geht das richtig ?

  Alt 4. Jan 2006, 13:38
Du must deine Interface-Zeiger "Marshalen" wenn Sie von mehreren Threads verwendet werden.
Windows Vista - Eine neue Erfahrung in Fehlern.
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#3

Re: COM Objekte in Threads. Wie geht das richtig ?

  Alt 4. Jan 2006, 14:02
Zitat von Bernhard Geyer:
Du must deine Interface-Zeiger "Marshalen" wenn Sie von mehreren Threads verwendet werden.
Danke, das sieht vielversprechend aus.

Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
jensw_2000
(Gast)

n/a Beiträge
 
#4

Re: COM Objekte in Threads. Wie geht das richtig ?

  Alt 4. Jan 2006, 21:49
Es läuft.

Ich rufe im Mainthread (Initialization Abschnitt) und im Constructor der einzelnen WorkerThreads CoInitializeEx(nil, COINIT_MULTITHREADED) auf. Den Rest musste ich nicht verändern.

Hat diese Variante entscheidende Nachteile gegenüber CoMarshalInterThreadInterfaceInStream und Co. ?


Schöne Grüße,
Jens
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:38 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz