Newsgroup: it.comp.lang.delphi
Titolo: Callbacks: metodi o procedure?

Salve.
Io sto sviluppando un programma utilizzando una libreria (che non ho 
sviluppato io e che non posso modificare). Questa libreria si basa in 
molti punti su un meccanismo di callbacks, ovvero gli passo il puntatore 
di una funzione e questa viene chiamata quando occorre dalla libreria 
per notificare certi eventi.
Il problema e' che questa libreria vuole "procedure regolari", non di 
oggetti. Io volevo fare una serie di classi per incapsulare le chiamate, 
ma non posso usare i metodi delle classi come callbacks.
I callbacks sono dichiarati cosi':
type TXXXXXEvent = procedure(param:integer);
mentre a me "servirebbero":
type TXXXXXEvent = procedure(param:integer) of object;
Che soluzione posso adottare? Se creo delle procedure statiche non posso 
associare loro una classe..
Grazie.

 associare loro una classe..
Le procedure statiche di callback che vengono eseguite contengono 
qualche riferimento che permetterebbe di distinguere da quale elemento 
(non so con cosa stai lavorando) provengono le notifiche?
In tal caso, potresti adottare comunque procedure statiche per 
raccogliere TUTTE le notifiche, poi in base al parametro che indica a 
quale elemento si riferiscono, cercare tale elemento (appartenente ad 
una classe creata da te) istanziato precedentemente e inserito in una 
lista, e richiamare un metodo che scateni un evento o che esegua 
operazioni collaterali.
In definitiva, se hai possibilità di distinguere a quale entità si 
riferisce la notifica ricevuta, la tua procedura statica di callback 
potrebbe fungere da "dispatcher" di messaggi, indirizzandoli verso 
l'oggetto che rappresenta tale entità.
Non so se sono riuscito ad illustrare correttamente il concetto... :-)
Per dire la verità, non so nemmeno se è applicabile al tuo contesto, ma 
sarai tu a fornire ulteriori indicazioni. :-)
Ciao!
-- 
Marco «Alka» Breveglieri
  ABLS Team S.n.c. - Software & Web
  Via De Gasperi, 14
  42019 Scandiano (Reggio Emilia)
 
http://www.abls.it

 sarai tu a fornire ulteriori indicazioni. :-)
Sto lavorando con una libreria di widget per la gestione di interfacce 
utente. La libreria e' abbastanza "oggettizzata", ma le api sono plain.
Ho il sospetto che non ci sia un modo pulito per fare questa cosa, 
sarebbe un bel peccato..
Qualche altro suggerimento ? :)

 Qualche altro suggerimento ? :)
Se dovessi procedere con un simile progetto, io andrei avanti con la 
tabella di lookup cercando di ottimizzarla al massimo...quanti sono gli 
oggetti di cui devi disporre all'interno di questa libreria e per i 
quali ottieni un callback distinto?
Non mi viene in mente nient'altro purtroppo, a meno che non vengano 
messi a disposizione dalla libreria altri metodi di callback oltre a 
quello della semplice "chiamata a procedura". :-(


Il problema dei puntatori a metodi č che sono strutture dati a 64 bit
(istanza + metodo), non semplici puntatori a funzione a 32 bit. Per di piů
i metodi hanno sempre il parametro implicito Self sullo stack, e non sono
pertanto compatibili con una normale chiamata a funzione.
Se la libreria permette di passare un parametro "utente" di 32 bit alla
callback, allora puoi usare quello per passare un puntatore all'istanza
della classe, e nella callback utilizzarlo per chiamare un metodo di
quell'istanza. 
Ad esempio questo č un esempio della callbak utilizzata da SHBrowseForFolder:
function BrowseCallback(hwnd: HWND; uMsg: UINT; lParam:  LPARAM;
  lpData: LPARAM): integer; stdcall;
begin
...
case uMsg of
 BFFM_SELCHANGED:
   TLDSBrowseFolderDialog(lpData).DoItemChanged(PItemIDList(lparam));
...
end;
lpData č un parametro a disposizione dell'utente, Windopws non lo usa e
semplicemente lo passa alla callback. Io ho incapsulato la chiamata in una
classe TLDSBrowseFolderDialog, che quando chiama la funzione passa come
parametro lpData il valore di Self:
with BrowseInfo do
...
  lpfn := @BrowseCallback;
  lParam := Integer(Self);
...
in modo che dalla callback ho accesso all'istanza della classe con un
semplice cast.
Se la callback non prevede meccanismi di questo tipo, mi fa pensare che la
libreria non č rientrante (thread safe), perché non c'č modo di sapere a
quale chiamata la callback si riferisce, a meno di non passare indirizzi
diversi ogni volta... Ma se non puoi avere istanze diverse della classe
che chiamano contemporaneamene la stessa funzione. A questo punto una
classe singleton e della callback statiche dovrebbero essere piů che
sufficienti. Bisognerebbe capire com'č fatta queata libreria, e come va usata.
Luigi D. Sandon - D&amp;D Support Team
--- posted by geoForum on 
http://www.delphiedintorni.it