Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Tapi Callback Funktion darf nicht in Klasse sein (https://www.delphipraxis.net/171806-tapi-callback-funktion-darf-nicht-klasse-sein.html)

Sir Rufo 26. Nov 2012 15:32

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Zitat:

Zitat von Jumpy (Beitrag 1193045)
Mein Ziel ist es halt, das die sich nicht innerhalb einer Klasse befindliche CallBack-Prozedur, die ich der tapi bei der intitialisierung übergebe(n muss), die gefeuerten Events / Nachrichten, an meine Klasse weitergibt. Notfalls wohl dann wie bei Sir Rufo, wo die Callback auf eine global deklarierte Liste zugreifen kann in der sich (im meinem Fall nur die) eine Klasse registrieren kann, an die die Callbacks weitergeleitet werden sollen.

Aber das machst du doch schon ... du verwaltest doch schon eine Liste mit Callbacks

Sir Rufo 26. Nov 2012 15:42

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Allerdings hätte ich auch einiges an Verbesserungen zum Code:
  1. MyTapi ist ein Singleton und sollte auch entsprechend implementiert werden z.B. mit einem Interface
    Delphi-Quellcode:
    interface

    type
      IFoo = interface
        ['{10C358B9-FCF2-4CAF-9F35-65DDDD4C6039}']
        procedure DoSomething;
      end;

    function MyFoo : IFoo;

    implementation

    type
      TFoo = class( TInterfacedObject, IFoo )
        procedure DoSomething;
      end;

    var
      _MyFoo : IFoo;

    procedure TFoo.DoSomething;
    begin

    end;

    function MyFoo : IFoo;
    begin
      if not Assigned( _MyFoo ) then
        _MyFoo := TFoo.Create;
      Result := _MyFoo;
    end;
  2. Du verwaltest eine Liste mit Callbacks, die dann aufgerufen werden. Warum nimmst du dann nicht Methoden? Du rufst die auf, dann kannst du auch bestimmen, was du aufrufst.
    Delphi-Quellcode:
    type
      TTapiCallbackMethod = procedure ( hDevice, dwMsg, {dwCallbackInstance, } dwParam1, dwParam2, dwParam3 : Cardinal ) of object;

Jumpy 26. Nov 2012 16:07

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Das oben gezeigte ist auszugsweise der Ist-Zustand, von dem ich ja weg will. Daher sind Verbesserungsvorschläge gerne gesehen. Mein irgendwann fertiges TapiApp-Object soll wie z.Zt. MyTapi eine Liste von Callback-Funktionen verwalten. Diese können dann tatsächlich so aussehen wie ich das will, sprich welche Parameter usw. Zu deinem

Delphi-Quellcode:
type
  TTapiCallbackMethod = procedure ( hDevice, dwMsg, {dwCallbackInstance, } dwParam1, dwParam2, dwParam3 : Cardinal ) of object;
könnte dann vllt. noch ein:
Delphi-Quellcode:
  TTapiCallbackMethods = Array of TTapiCallbackMethod
kommen. Geht das? Oder sind so Methodenzeiger (das ist das doch) besser in einer T(Object)List o.ä. aufgehoben?

-------

Es gibt wenn man so will 2 Arten von Callback Funktionen. Eine "Master"-CallBack-Funktion für die Tapi ausserhalb von Objekten, die aber auch an mein Objekt alles weitergeben soll und dann andere Callback-Funktionen (diesmla gerne auch von anderen Objekten), die in meinem Objekt gelistet sind und an die so auch die ursprüngliche Tapi-Message (ggf. in angepasster Form) weitergegeben wird.

-------
Wenn ich nun MyTapi als Singelton (muss ich mir nochmal genauer anschauen) umsetzte, kann ich das denn auch in meiner aussserhalb von Objekten (nur im Application-Kontext) deklarierten CallFunktion benutzen?

Sir Rufo 26. Nov 2012 16:12

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Zitat:

Zitat von Jumpy (Beitrag 1193050)
könnte dann vllt. noch ein:
Delphi-Quellcode:
  TTapiCallbackMethods = Array of TTapiCallbackMethod
kommen. Geht das? Oder sind so Methodenzeiger (das ist das doch) besser in einer T(Object)List o.ä. aufgehoben?

Völlig wumpe, die Struktur, wie gespeichert wird, würde ich eh nicht nach aussen geben. Das Interface hat einfach zwei Methoden: AddMethod, RemoveMethod. Den Rest interessiert keinen der von aussen schaut.
Zitat:

Zitat von Jumpy (Beitrag 1193050)
Wenn ich nun MyTapi als Singelton (muss ich mir nochmal genauer anschauen) umsetzte, kann ich das denn auch in meiner aussserhalb von Objekten (nur im Application-Kontext) deklarierten Funktion benutzen?

Öh, ja warum nicht ... das Singleton sorgt nur dafür, dass es max. 1 Instanz gibt, mehr nicht

shmia 26. Nov 2012 17:17

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Das Weiterleiten einer Callback-Funktion auf die Callback-Methode ist doch ganz einfach!
Delphi-Quellcode:
procedure priv_MyCallback(hDevice,
                          dwMsg,
                          dwCallbackInstance,
                          dwParam1,
                          dwParam2,
                          dwParam3: Cardinal); stdcall;
begin
  if dwCallbackInstance = 0 then
  begin
    // Oh ohhh, das sollte nie vorkommen (wäre ganz klar ein Fehler des Programmierers)
    Assert(False);
  end
  else
  begin
     try
        TMyTapi(dwCallbackInstance).MyCallback(hDevice,
                          dwMsg,
                          dwParam1,
                          dwParam2,
                          dwParam3);
    except
       // Exception loggen oder anzeigen
       // auf jeden Fall sollte keine Exception dem Aufrufer um die Ohren fliegen
    end;
  end;
end;

DeddyH 26. Nov 2012 17:58

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Das ist doch ziemlich genau das, was ich weiter vorn bereits gesagt habe. Mir ist nur noch nicht klar, wie man dwCallbackInstance belegen kann.

Sir Rufo 26. Nov 2012 18:19

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Zitat:

Zitat von DeddyH (Beitrag 1193077)
Das ist doch ziemlich genau das, was ich weiter vorn bereits gesagt habe. Mir ist nur noch nicht klar, wie man dwCallbackInstance belegen kann.

Beim Initialisieren gibt man das mit an

Jumpy 27. Nov 2012 10:09

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Zitat:

dwCallbackInstance
Instance data passed back to the application, which was specified by the application in the dwCallBackInstance parameter of lineInitializeEx. This DWORD is not interpreted by TAPI.
dwCallBackInstance = hInstance aus der Initialisierung?

Zitat:

LONG WINAPI lineInitializeEx(
LPHLINEAPP lphLineApp,
HINSTANCE hInstance,
LINECALLBACK lpfnCallback,
LPCSTR lpszFriendlyAppName,
LPDWORD lpdwNumDevs,
LPDWORD lpdwAPIVersion,
LPLINEINITIALIZEEXPARAMS lpLineInitializeExParams
);

hInstance
Instance handle of the client application or DLL. The application or DLL can pass NULL for this parameter, in which case TAPI uses the module handle of the root executable of the process (for purposes of identifying call handoff targets and media mode priorities).

aus der SysInit:
HInstance: LongWord; { Handle of this instance }
Hab mich heut morgen ein wenig durch die SDK gekämpft und da nichts weiteres dazu gefunden, wo das ausser in lineInitializeEx gesetzt werden könnte. So wie das bei unserem alten Code gesetzt wird, vermute ich da eher einen Handle o.ä. auf die Application:
Delphi-Quellcode:
var priv_hInstance:Cardinal;
    priv_hInstance := hInstance; //hInstance aus Sysinit
    lineInitializeEX(@priv_LineApp,priv_hInstance,priv_MyCallback,//...
Sehe leider nicht, wie ich das gebrauchen kann, um auf mein Objekt zu zeiegn. Werde also versuchen mein TapiApp-Object als Singelton zu implementieren.

himitsu 27. Nov 2012 10:17

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Zitat:

Zitat von Jumpy (Beitrag 1193174)
Delphi-Quellcode:
var priv_hInstance:Cardinal;
    priv_hInstance := hInstance; //hInstance aus Sysinit
    lineInitializeEX(@priv_LineApp,priv_hInstance,priv_MyCallback,//...
Sehe leider nicht, wie ich das gebrauchen kann, um auf mein Objekt zu zeiegn.

Statt hInstance den Instanz-Zeiger deines Objektes übergeben? :angle2:

Jumpy 27. Nov 2012 10:31

AW: Tapi Callback Funktion darf nicht in Klasse sein
 
Kommando zurück. Hab komplett an der falschen Stelle gesucht. Der Parameter wird bei lineOpen übergeben, das man für jede Telefonleitung, die man überwachen will, aufruft.

Zitat:

LONG lineOpen(
HLINEAPP hLineApp,
DWORD dwDeviceID,
LPHLINE lphLine,
DWORD dwAPIVersion,
DWORD dwExtVersion,
DWORD dwCallbackInstance,
DWORD dwPrivileges,
DWORD dwMediaModes,
LPLINECALLPARAMS const lpCallParams
);

dwCallbackInstance

User-instance data passed back to the application with each message associated with this line or addresses or calls on this line. This parameter is not interpreted by the Telephony API.
Bei uns wurde da scheinbar immer die Nummer der Leitung übergeben, was aber unnötig ist, da man da ja auch den Handle der Leitung bekommt.
Also ist es ja vllt. doch möglich da einen Verweis auf mein Objekt hinzukriegen. Hoffe es hilft mir noch jemand nach der ganzen Verwirrung.

Wenn ich innerhalb meines Objectes für jede Line lineOpen aufrufe, wie kann ich dann dabei einen Pointer(?) auf mein Objekt in dwCallbackInstance mitgeben, das ja vom Typ DWORD ist?

Und wie muss ich dieses DWORD in der Callback-Funktion auswerten, um da wieder auf mein Objekt zu kommen? So wie shmia das andeutet, indem ich das in mein Objekt caste?
TMyTapi(dwCallbackInstance).


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:44 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz