2013-08-22 13 views
5

Piszę DLL Delphi. W Delphi DLL chciałbym zaimplementować funkcję zwrotną, ta funkcja zwrotna powinna oddzwonić do programu wywołującego Delphi. Głównym celem funkcji wywołania zwrotnego jest to, że w bibliotece DLL wystąpi pewna długa operacja, ale raport o postępach (za pośrednictwem paska postępu) i anulowanie operacji powinny wystąpić w programie wywołującym Delphi.Funkcja oddzwaniania między Delphi DLL a Delphi EXE

Chciałbym uzyskać pomoc dotyczącą prawidłowego wdrażania funkcji wywołania zwrotnego w bibliotece DLL. Mogę kontynuować aż do przypisania funkcji wywołania zwrotnego z EXE, ale nie wiem jak zainicjować połączenie z samej biblioteki DLL.

to część definicji (używany przez EXE oraz DLL): Plik

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; 

poprzez PTDLLParameters przekazywanych DLL, co wynika z EXE Delphi :

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

ładuje DLL

..... 
    ..... 

nazywając DLL

CompressionCreateLibrary(DLLParameters); 
    .... 

pewnych operacji

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

plik DLL:

Funkcja ta powinna być wywoływana z pewnej części DLL czyniąc postęp z powrotem do EXE dotyczące rzeczywistego działania:

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

Myślę, że ta część powinna być ok:

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

begin 

    DLLParametersID.CallbackFunction:= @DLLCallback; 

end; 

Proszę mi pomóc jak wdrożyć część zwrotnej właściwie w DLL. Doceniony zostanie przykładowy kod. Podczas inicjalizacji debugowania działa dobrze, ale wywołanie zwrotne nie powiedzie się. Z góry dziękuję.

+0

Nie mam pojęcia, o co pytasz. Jest dość duża ilość fragmentów kodu, które trudno złożyć w całość. A następnie "wywołanie zwrotne nie powiedzie się". Er, co oznacza niepowodzenie? A co powie ci debugowanie? Proszę mi powiedzieć, że zrobiłeś trochę debugowania. Inne uwagi: 1. Nie używaj pakowanych. 2. Nie używaj @ do pobierania zmiennych proceduralnych. –

+1

To jest ** prawie ** dobre pytanie. Pokazałeś swój kod i wyjaśniłeś, po co każdy był. Nie podałeś nieistotnego kodu, ale pokazałeś wszystkie ważne deklaracje. Kluczową rzeczą, którą ** nie zawierałeś, jest opis tego, co jest nie tak. "Fails" nie jest wystarczająco dobre. Co się właściwie dzieje i czego się spodziewałeś? –

+0

Więcej komentarzy. Nie ma potrzeby przydzielania sterty, użyj zmiennej ze stosu. I przekazywanie wskaźników do zapisów jest prymitywne. Parametr const typu rekordowego jest z pewnością tym, czego potrzebujesz. –

Odpowiedz

4

Twoja instrukcja przypisania jest cofana. W funkcji DLL, DLLParametersID przechowuje informacje o oddzwonienie, ale potem można zastąpić go z zmiennej globalnej:

DLLParametersID.CallbackFunction:= @DLLCallback; 

Zmienne te do przypisaćDLLCallback.

+0

jeśli to zrobię, otrzymuję błąd kompilatora (nie ma wystarczającej liczby rzeczywistych parametrów) – fingomajom

+0

Działa, zamieniłem to. Dziękuję Ci. – fingomajom

+0

Zalecam, abyś spróbował ustawić punkty przerwania i przechodząc przez kod, a następnie nauczyć się patrzeć na wartości swoich zmiennych. Jeśli przegapisz kierunek zadania, prawdopodobnie przegapisz DUŻO tego, co może wydawać się, że inni deweloperzy są PRZESZKODNYMI rzeczami! Jeśli spróbujesz tego pojedynczego kroku, możesz zobaczyć, co naprawdę dzieje się, gdy twój kod działa. –