2012-01-09 27 views
7

Tôi có thư viện động mà tôi tải bằng cách sử dụng dlopen() và sau đó tải xuống bằng cách sử dụng dlclose();unload thư viện động cần hai cuộc gọi dlclose()?

Nếu tôi không bao gồm bất kỳ mã c mục tiêu nào dlopen() cần một cuộc gọi dlclose() gọi là hành vi mong đợi. Nhưng khi tôi bao gồm bất kỳ mã c mục tiêu nào để nhắm mục tiêu, tôi có vấn đề rằng tôi cần phải thực hiện hai cuộc gọi dlclose() tới thư viện đã tải để tải xuống.

Đây có phải là hành vi mong đợi không? Làm thế nào tôi có thể sửa chữa nó?

+0

Bạn có chắc chắn rằng thư viện của bạn không phải là 'dlopen'-ed hai lần theo một cách ẩn? Hoặc có thể là lỗi-ví dụ bộ nhớ bị rò rỉ- là ghi đè bộ nhớ gần xử lý 'dlopen'-ed? –

+0

dlopen giữ một số tham chiếu về việc xử lý thư viện. Nếu dlopen được thực hiện hai lần, nó sẽ yêu cầu hai dlclose() để dỡ bỏ thư viện. Có thể thư viện động được yêu cầu nếu bạn bao gồm mã obj-C không? Trong trường hợp này dlopen đầu tiên có thể được thực hiện khi bạn chạy chương trình của bạn – Finslicer

+0

Có Tôi chắc chắn rằng nó không được mở hai lần. Bạn có thể thử một chương trình đơn giản trong chính với dlopen theo sau là dlclose với thư viện động có mã c mục tiêu. – MacGeek

Trả lời

26

Tôi nhận thấy rằng bạn đang sử dụng dlopen, không phải CFBundle hoặc NSBundle. Tuy nhiên, hướng dẫn Code Loading Programming Topics nói điều này:

Trong các ứng dụng Cocoa, bạn không nên sử dụng CFBundle thói quen để nạp và xả mã thực thi, vì CFBundle không natively hỗ trợ thời gian chạy Objective-C. NSBundle tải đúng các ký hiệu Objective-C vào hệ thống thời gian chạy, nhưng không có cách nào để dỡ các gói Cocoa một khi được tải do giới hạn thời gian chạy.

và điều này:

Do giới hạn trong hệ thống runtime Objective-C, NSBundle không thể dỡ bỏ mã thực thi.

Điều này làm cho tôi nghi ngờ rằng khi bạn tải thư viện của bạn, nó tự đăng ký với thời gian chạy Objective-C, và thời gian chạy gọi dlopen trên thư viện một lần nữa (hoặc bằng cách nào đó làm tăng của thư viện số tài liệu tham khảo).

Tôi đã tìm kiếm mã nguồn runtime Objective-C và thấy this:

// dylibs are not allowed to unload 
// ...except those with image_info and nothing else (5359412) 
if (result->mhdr->filetype == MH_DYLIB && _hasObjcContents(result)) { 
    dlopen(result->os.dl_info.dli_fname, RTLD_NOLOAD); 
} 

Vì vậy, có, thời gian chạy Objective-C được gọi dlopen vào thư viện của bạn đặc biệt để ngăn ngừa nó khỏi bị bốc dỡ. Nếu bạn lừa dối và gọi dlclose hai lần, bạn sẽ mong đợi những điều xấu xảy ra.

+0

+1 câu trả lời tuyệt vời! – Till

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