2013-08-22 44 views
5

Sto scrivendo una DLL Delphi. Nella DLL Delphi vorrei implementare una funzione di callback, questa funzione di callback dovrebbe richiamare il programma Delphi del chiamante. Lo scopo principale della funzione di callback è che durante la DLL si verificheranno determinate operazioni lunghe, ma la segnalazione dei progressi (tramite una barra di avanzamento) e l'annullamento delle operazioni dovrebbero avvenire nel programma Delphi del chiamante.Funzionalità di callback tra Delphi DLL e Delphi EXE

Vorrei ottenere qualche supporto su come implementare correttamente la funzione di callback all'interno della DLL. Posso procedere fino all'assegnazione della funzione di callback passata dall'EXE, ma non so come avviare una chiamata dalla DLL stessa.

Questa è la parte definizione (usata da EXE e DLL): file di

uses Windows; 

Type 
    PTCallBackStruct = ^TCallBackStruct; 
    TCallBackStruct = packed record 
    Handle: THandle; 
    Caller: Pointer;   
    FileSize: LongInt; 
end; 

type 

TFunctionPointerType = function(ZCallbackRec: PTCallBackStruct): Longbool; 
    stdcall; 

type 
    PTDLLParamaters = ^TDLLParamaters; 
    TDLLParamaters = packed record 
    Handle: THandle; 
    Caller: Pointer; 
    CallbackFunction: TFunctionPointerType; 
end; 

var 
    DLLCallback: TFunctionPointerType; 

EXE:

uses ....  

type 

    function DLL_Callback(ZCallBackRec: PTCallBackStruct): LongBool; stdcall; 
    forward; 

    implementation 

    function DLL_Callback(ZCallBackRec: PTCallBackStruct): LongBool; stdcall; 
    begin 
     // progress reporting this function should be called back from 
     //the DLL. The Handle and Self parameter should help with identifying 
     // which object initiated the callback 
    end; 

via PTDLLParameters passati alla DLL come segue dal exe Delphi :

// init callback 
DLLParameters := AllocMem(SizeOf(TDLLParamaters)); 
with DLLParameters^ do 
    begin 
    Handle := Application.Handle; 
    Caller := Self; 
    CallbackFunction:= DLL_Callback; 
    end; 

caricamento della DLL

..... 
    ..... 

chiama la DLL

CompressionCreateLibrary(DLLParameters); 
    .... 

alcune operazioni

 Free DLL 
    .... 
    ..... 
    FreeMem(DLLParameters); 

di file DLL:

Questa funzione deve essere chiamata da certa parte della DLL riportare i progressi all'EXE relative al funzionamento effettivo:

function CallCallBackFromDLL(Size: integer): Integer; 
    begin 
     // 
     .... 
     set up callbackstruct 
     .... 
     // calling back 
     DLLCallback(CallbackStruct); 
     end; 

Credo che questa parte dovrebbe essere ok:

// main init call assigning the callback function to the DLL 
function CompressionCreateLibrary(DLLParametersID: PTDLLParamaters): Integer; 

begin 

    DLLParametersID.CallbackFunction:= @DLLCallback; 

end; 

Si prega di aiutarmi come implementare la parte richiamata correttamente nella DLL. Qualche esempio di codice sarebbe apprezzato. Mentre l'inizializzazione del debug funziona bene, ma fallire la callback. Grazie in anticipo.

+0

Non ho idea di cosa stai chiedendo. C'è una quantità piuttosto grande di estratti di codice che sono difficili da mettere insieme. E poi "fare fallire una callback". Ehm, cosa significa fallire? E cosa ti dice il tuo debugging. Per favore dimmi che hai fatto un po 'di debug. Altri commenti: 1. Non usare imballato. 2. Non utilizzare @ per ottenere variabili procedurali. –

+1

Questa è ** quasi ** una buona domanda. Hai mostrato il tuo codice e hai spiegato a cosa serviva ciascun bit. Non hai incluso codice irrilevante, ma hai mostrato tutte le dichiarazioni importanti. La cosa fondamentale che tu ** non hai incluso è una descrizione di ciò che è sbagliato. "Fails" non è abbastanza buono. Cosa succede realmente e cosa ti aspetti che succeda invece? –

+0

Altri commenti. Non è necessario allocare l'heap, utilizzare una variabile dallo stack. E passare i puntatori ai record è grezzo. Un parametro const del tipo di record è sicuramente quello che ti serve. –

risposta

4

Il tuo estratto conto è arretrato. Nella funzione DLL, DLLParametersID contiene le informazioni sulla richiamata, ma poi sovrascrivere con il tuo variabile globale:

DLLParametersID.CallbackFunction:= @DLLCallback; 

Swap coloro ai assegnareDLLCallback.

+0

se faccio questo, ricevo un errore del compilatore (non abbastanza parametri effettivi) – fingomajom

+0

Funziona L'ho scambiato. Grazie. – fingomajom

+0

Posso consigliare di provare a impostare i punti di interruzione e passare il codice, quindi imparare a guardare i valori delle variabili. Se puoi perdere la direzione di un incarico, probabilmente manchi MOLTO di ciò che potrebbe sembrare agli altri sviluppatori come cose OVVIO! Se provi la cosa a passo singolo, puoi vedere cosa succede veramente quando il tuo codice viene eseguito. –