2013-08-13 27 views
5

Tôi có một dll xuất một chức năng trả về Giao diện.Làm cách nào để đảm bảo phiên bản Giao diện được giải phóng trước khi FreeLibrary được gọi là

Tôi đã tạo trình bao bọc cho các hàm LoadLibrary, GetProcAddress và FreeLibrary được sử dụng để gọi hàm đã xuất.

TInterfaceGetter = class 
private 
... 
public 
    constructor Create; 
    destructor Destroy; override; 
    function GetInterface: IMyInterface; 
end; 

Trình bao bọc này sẽ tải xuống dll và lưu giữ xử lý mô đun và địa chỉ proc của hàm được xuất khi GetInterface được gọi lần đầu tiên. Các cuộc gọi đến FreeLibrary xảy ra trong destructor của wrapper.

Mọi thứ hoạt động tuyệt vời trừ khi mã máy khách treo vào tham chiếu giao diện sau khi giải phóng trình bao bọc. Khi tham chiếu giao diện cuối cùng đi ra ngoài phạm vi kết quả cuộc gọi đến _IntfClear làm tăng một sự vi phạm truy cập vì dll cũng như bất kỳ bộ nhớ nó đã sử dụng đã được dỡ xuống từ không gian bộ nhớ của khách hàng.

Tôi có thể xử lý điều này một cách duyên dáng như thế nào? Làm thế nào để thực thi COM toàn diện xử lý kịch bản này?

Trả lời

6

COM xử lý vấn đề này bằng cách chuyển trách nhiệm sang DLL. DLL cần triển khai và xuất hàm có tên DllCanUnloadNow. COM gọi nó đôi khi, và nếu nó trả về true, DLL có thể được dỡ bỏ.

Vậy chức năng này biết như thế nào? Các DLL theo dõi bao nhiêu đối tượng nó đưa ra thông qua các cuộc gọi đến DllGetClassObject, và nó biết bao nhiêu trong số những đối tượng vẫn còn sống. Trong triển khai mặc định COM DLL của Delphi, nó duy trì một số đối tượng toàn cầu, nhiều cách mà mỗi đối tượng duy trì số tham chiếu của riêng nó. Xem triển khai trong ví dụ: ComServ.pas.

Bạn có thể sử dụng cùng một kỹ thuật. Theo dõi chức năng GetInterface của bạn và những gì được phát hành. Xuất một chức năng khác để các chương trình máy chủ có thể hỏi xem có an toàn để dỡ bỏ thư viện của bạn hay không.

Một giải pháp thay thế sẽ là thay đổi DLL của bạn thành một COM DLL thực sự

Các vấn đề liên quan