2013-08-22 64 views
5

Tôi đang viết một DLL Delphi. Trong Delphi DLL tôi muốn thực hiện một chức năng gọi lại, chức năng gọi lại này nên gọi lại cho chương trình Delphi người gọi. Mục đích chính của chức năng gọi lại là hoạt động lâu dài nhất định sẽ xảy ra trong DLL, nhưng báo cáo tiến độ (thông qua thanh tiến trình) và hủy bỏ hoạt động sẽ xảy ra trong chương trình Delphi người gọi.Chức năng gọi lại giữa Delphi DLL và Delphi EXE

Tôi muốn nhận được một số hỗ trợ cách triển khai đúng chức năng gọi lại trong DLL. Tôi có thể tiến hành cho đến khi gán chức năng gọi lại được truyền từ EXE nhưng tôi làm nit biết cách bắt đầu cuộc gọi từ chính DLL đó.

Đây là phần định nghĩa (được sử dụng bởi EXE và DLL):

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 file:

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; 

qua PTDLLParameters truyền cho các DLL như sau từ exe Delphi :

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

tải DLL

..... 
    ..... 

gọi DLL

CompressionCreateLibrary(DLLParameters); 
    .... 

nhất định hoạt động

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

tập tin DLL:

Chức năng này nên được gọi là từ một phần nhất định của DLL làm cho tiến trình trở lại EXE liên quan đến hoạt động thực tế:

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

Tôi nghĩ rằng phần này nên được ok:

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

begin 

    DLLParametersID.CallbackFunction:= @DLLCallback; 

end; 

Xin hãy giúp tôi hiểu làm thế nào để thực hiện một phần callback đúng trong DLL. Một số mã ví dụ sẽ được đánh giá cao. Trong khi gỡ lỗi khởi tạo hoạt động tốt, nhưng làm cho một cuộc gọi lại không thành công. Cảm ơn bạn trước.

+0

Tôi không biết bạn đang hỏi gì. Có một số lượng lớn các trích đoạn mã khó có thể ghép lại với nhau. Và sau đó "thực hiện một cuộc gọi lại không thành công". Er, có nghĩa là gì? Và những gì bạn gỡ lỗi cho bạn biết. Vui lòng cho tôi biết bạn đã thực hiện một số gỡ lỗi. Các ý kiến ​​khác: 1. Không sử dụng đóng gói. 2. Không sử dụng @ để nhận các biến thủ tục. –

+1

Đây là ** gần như ** một câu hỏi hay. Bạn đã cho thấy mã của bạn, và bạn giải thích những gì từng bit được cho. Bạn không bao gồm mã không liên quan, nhưng bạn đã hiển thị tất cả các khai báo quan trọng. Điều quan trọng bạn ** không bao gồm là mô tả về những gì sai. "Không" không đủ tốt. Điều gì thực sự xảy ra, và bạn mong đợi điều gì sẽ xảy ra thay vào đó? –

+0

Nhận xét khác. Không cần phân bổ đống, sử dụng biến từ ngăn xếp. Và chuyển các con trỏ tới các bản ghi là thô. Một tham số const của loại bản ghi chắc chắn là những gì bạn cần. –

Trả lời

4

Tuyên bố gán của bạn bị lạc hậu. Trong hàm DLL, DLLParametersID giữ thông tin về các cuộc gọi lại, nhưng sau đó bạn ghi đè lên nó với biến toàn cục của bạn:

DLLParametersID.CallbackFunction:= @DLLCallback; 

Swap những để gánDLLCallback.

+0

nếu tôi làm điều này tôi nhận được một lỗi biên dịch (không đủ parametres thực tế) – fingomajom

+0

Nó hoạt động tôi swaped nó. Cảm ơn bạn. – fingomajom

+0

Tôi khuyên bạn nên thử đặt các điểm ngắt và bước qua mã của bạn, sau đó tìm hiểu xem các giá trị của các biến của bạn. Nếu bạn có thể bỏ lỡ hướng của một nhiệm vụ, bạn có thể bỏ lỡ một LOT của những gì có vẻ như các nhà phát triển khác là những điều OBVIOUS! Nếu bạn cố gắng điều duy nhất bước có thể bạn có thể thấy những gì thực sự xảy ra khi mã của bạn chạy. –