2012-04-30 26 views
9

Tôi đang gặp nhiều rắc rối khi xử lý một DLL mà tôi đã viết trong Delphi. Tôi đã thiết lập một chức năng DllMain sử dụng đoạn mã sau trong thư viện:Delphi DllMain DLL_PROCESS_DETACH được gọi trước DLL_PROCESS_ATTACH

begin 
    DllProc := DllMain; 
end. 

thủ tục DllMain của tôi trông như thế này:

procedure DllMain(reason: Integer); 
begin 
    if reason = DLL_PROCESS_DETACH then 
    OutputDebugString('DLL PROCESS DETACH') 
    else if reason = DLL_PROCESS_ATTACH then 
    OutputDebugString('DLL PROCESS ATTACH') 
    else if reason = DLL_THREAD_ATTACH then 
    OutputDebugString('DLL THREAD ATTACH') 
    else if reason = DLL_THREAD_DETACH then 
    OutputDebugString('DLL THREAD DETACH') 
    else 
    OutputDebugString('DllMain'); 
end; 

Những gì tôi phát hiện là cửa sổ mới dường như được gọi là (hai lần ?!) bởi người gọi (mà tôi không kiểm soát) trước khi ATTACH được gọi. Điều đó thậm chí có thể, hay tôi hiểu lầm về cách thức hoạt động của nó? Kỳ vọng của tôi là mọi cuộc gọi ATTACH sẽ được đáp ứng với một cuộc gọi DETACH phù hợp, nhưng điều đó dường như không đúng.

Điều gì sẽ xảy ra ở đây ?!

Trả lời

12

Thật không may khi begin được thực hiện trong mã dll của bạn, hệ điều hành đã được gọi là DllMain trong thư viện của bạn. Vì vậy, khi câu lệnh DllProc := DllMain; của bạn thực hiện thì đã quá muộn. Trình biên dịch Delphi không cho phép mã người dùng thực thi khi dll được gắn vào một tiến trình. Cách giải quyết đề nghị (nếu bạn có thể gọi đó là một cách giải quyết) là để gọi riêng DllMain chức năng của bạn mình trong một phần đơn vị initalization hoặc trong mã thư viện:

begin 
    DllProc := DllMain; 
    DllMain(DLL_PROCESS_ATTACH); 
end; 

các relevant documentation:

Note : DLL_PROCESS_ATTACH được truyền cho thủ tục chỉ khi mã khởi tạo của DLL gọi thủ tục và chỉ định DLL_PROCESS_ATTACH làm tham số.

+0

Hmm ... Tôi đã hy vọng đây sẽ là giải pháp cho tất cả các vấn đề của tôi, nhưng kiến ​​thức bổ sung này (mặc dù đúng và trả lời câu hỏi của tôi) vẫn chưa khắc phục được vấn đề của tôi. Có vẻ như tôi sẽ phải tạo một câu hỏi khác :). Cảm ơn bạn đã giúp đỡ! – aardvarkk

+0

Những gì bạn không hiểu. Đó là tất cả ở đây ngay trong câu hỏi này. Lệnh gọi duy nhất của DllMain xảy ra trước khi mã của bạn có thể thực thi là cho 'DLL_PROCESS_ATTACH'. Vì vậy, bạn chỉ cần viết nó theo cách Sertac nói và tất cả đều tốt. –

+0

Không, điều này hoàn toàn rõ ràng. Tôi hiểu nó và có thể thực hiện nó. Nó đã tiết lộ, mặc dù, rằng câu trả lời cho vấn đề lớn hơn của tôi (mà tôi đã hy vọng có liên quan đến điều này), không phải là trong thực tế liên quan đến vấn đề này. Vì vậy, tìm kiếm vẫn tiếp tục! – aardvarkk

-1

Những gì tôi đang tìm kiếm là cửa sổ mới dường như được gọi là (gấp đôi ?!) bởi một người gọi (mà tôi không kiểm soát được) trước khi đính kèm là bao giờ gọi.

Theo "Lập trình Windows phiên bản thứ 5" của Petzold.
DLL_PROCESS_ATTACH được gọi khi ứng dụng bắt đầu và
DLL_THREAD_ATTACH khi bắt đầu một chuỗi mới bên trong ứng dụng đính kèm.
DLL_PROCESS_DETACH được gọi khi một ứng dụng được đính kèm trong đơn đăng ký của bạn.
DLL_THREAD_DETACH được gọi khi một chuỗi bên trong một ứng dụng đính kèm thoát.

Lưu ý rằng có thể DLL_THREAD_DETACH được gọi mà không cần sửa đổi trước đó DLL_THREAD_ATTACH.
Điều này xảy ra khi chủ đề được bắt đầu trước cho ứng dụng liên kết đến dll.
Điều này chủ yếu xảy ra khi một ứng dụng tải thủ công dll bằng cách sử dụng LoadLibrary thay vì liên kết tĩnh tại thời gian biên dịch.

+0

Tôi không hiểu. Bạn có nghĩa là một chủ đề mà không có một quá trình? Và 'LoadLibrary' sẽ không dẫn đến 'DLL_PROCESS_ATTACH'? –

+0

Điều này dường như không giải thích tại sao 'DLL_PROCESS_DETACH' đang diễn ra nhiều lần. –

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