2012-02-08 36 views
6

Tôi đang sử dụng chức năng LoadLibrary để tải một DLL trong Windows. Câu hỏi của tôi là: Nếu tôi gọi phương thức này nhiều hơn một lần cho cùng một DLL, tôi có xử lý các trường hợp DLL khác nhau không, hoặc tất cả chúng sẽ chỉ đến cùng một cá thể không?Tải một DLL nhiều hơn một lần?

Ngoài ra, hành vi này có liên quan như thế nào với các tệp Linux SO, có giống nhau hay hoàn toàn khác và tôi có thể đưa ra những giả định nào về vấn đề này? Cảm ơn.

+0

Bạn có muốn một phiên bản DLL riêng biệt (và trạng thái toàn cầu của nó) không? –

+0

@DavidHeffernan Có thể, nhưng chỉ khi nó có thể được thực hiện trong Linux là tốt. Tôi đang cố gắng tìm hiểu cách mọi thứ 'thường' hoạt động như thế nào. Nếu những gì bạn mô tả là có thể, tôi muốn được biết làm thế nào. –

+1

Nó hoạt động tương tự trong các hệ điều hành. Có một thủ thuật bẩn để có được các trường hợp riêng biệt của DLL. Mỗi khi bạn cần một phiên bản mới, hãy sao chép tệp đó vào một vị trí tạm thời và đặt cho nó một tên duy nhất. Bằng cách đó bạn buộc hệ thống tải một mô-đun mới. Đôi khi tôi đã sử dụng kỹ thuật này để làm việc xung quanh các thư viện không phải là luồng an toàn do thiết kế kém và sử dụng trạng thái toàn cầu. –

Trả lời

11

Các trạng thái tài liệu MSDN: Hệ thống

duy trì một số tài liệu tham khảo cho mỗi quá trình trên tất cả nạp mô-đun. Gọi LoadLibrary tăng số lượng tham chiếu. Gọi hàm hàm FreeLibrary hoặc FreeLibraryAndExitThread sẽ giảm số lượng tham chiếu . Hệ thống sẽ tải một mô-đun khi số tham chiếu đạt 0 hoặc khi quá trình chấm dứt (bất kể số tham chiếu ).

Vì vậy, có vẻ như việc tải mô-đun nhiều lần (không có cuộc gọi phù hợp với FreeLibrary) sẽ trả về cùng một điều khiển.

3

Nếu tệp DLL đã được tải, LoadLibrary sẽ chỉ trả về địa chỉ của thư viện trong bộ nhớ. Tuy nhiên, DllMain không được gọi lại với DLL_PROCESS_ATTACH khi lần tải thứ hai được thử. Xử lý theo nghĩa của các thư viện chỉ là các vị trí bộ nhớ, vì vậy giá trị bạn nhận được lần thứ hai xung quanh phải giống như lần đầu tiên.

Theo như các tệp SO của Linux, tôi không thấy lý do tại sao chúng sẽ tải hai lần. Tuy nhiên, một người khác sẽ phải cân nhắc về điều này để cung cấp cho bạn một câu trả lời đúng.

2

Đối với Linux chia sẻ đối tượng, từ dlopen(3) manpage:

Nếu cùng một thư viện được nạp lại với dlopen(), cùng tập tin xử lý được trả về. Thư viện dl duy trì số lượng tài liệu tham khảo cho xử lý thư viện, vì vậy một thư viện động không deallocated cho đến khi dlclose() đã được gọi vào nó nhiều lần như dlopen() đã thành công vào nó. Quy trình _init(), nếu có, chỉ được gọi là. Nhưng cuộc gọi tiếp theo với RTLD_NOW có thể buộc giải quyết biểu tượng cho thư viện trước đó được tải bằng RTLD_LAZY.

+0

là quy trình này cho mỗi quy trình hay cho tất cả các quy trình? – g19fanatic

+0

@ g19fanatic - cho cùng một quy trình. – cha0site

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