2010-08-04 25 views
5

Tôi mới tham gia C++/CLI, vì vậy hãy chịu với tôi ...Làm thế nào để dọn dẹp công cụ .NET khi một DLL C++/CLI bị dỡ xuống?

Tôi đang làm việc trên một DLL hỗn hợp C++/CLI, hoạt động như một cầu nối giữa quá trình Win32 và hội đồng .NET. . Trong DLL, tôi cần một số công cụ .NET để có mặt trong suốt thời gian tồn tại của DLL. Khởi tạo không phải là một vấn đề lớn, nhưng tôi không thể tìm ra khi nào tôi có thể dọn dẹp một cách an toàn các thứ .NET. Các cơ sở C++ thông thường (DLL_PROCESS_DETACH, biến toàn cục và d'tors tĩnh cục bộ) tất cả dường như được gọi sau khi CLR đã biến mất.

Vì vậy, cách để nhận thông báo rằng DLL sắp tách ra khỏi CLR, vì vậy tôi có thể giải phóng tham chiếu .NET mà tôi giữ?

Trả lời

2

Vâng, trả lời câu hỏi của riêng tôi dường như vụng về, nhưng điều này đã không được đề xuất bởi bất cứ ai khác, và đó là những gì tôi đang tìm kiếm ... vậy:

quay ra Microsoft cung cấp một sự thay đổi kỳ lạ của onexit, được gọi là _onexit_m, nên được sử dụng trong các DLL chế độ hỗn hợp. Khi sử dụng _onexit_m để đăng ký chức năng gọi lại (được quản lý), chức năng đó sẽ được gọi khi DLL sắp được tải xuống, nhưng trước khi CLR bị tắt. Nó tương tự như AppDomain.DomainUnload, suggested by Ben Voigt, nhưng vì một số lý do tôi không thể lấy DomainUnload để làm việc và _onexit_m đơn giản hơn để sử dụng IMHO.

0

Điều này có thể không áp dụng cho phía C++ của .NET, nhưng theo hiểu biết của tôi, cách duy nhất để có được CLR phát hành một hội đồng được tải là loại bỏ AppDomain; và trừ khi bạn đã thiết kế trong quản lý AppDomain thủ công, bạn có thể chỉ có AppDomain ban đầu - làm cho việc xử lý tương đương với việc giết ứng dụng của bạn.

+0

Tôi không cố gắng phát hành một hội đồng - tôi chỉ đang cố gắng giải phóng các tham chiếu đến các đối tượng .NET mà tôi đã tạo và đã giữ trong suốt thời gian tồn tại của DLL ... – eran

+0

Các đối tượng có trong đó không. NET dùng một lần? Trong trường hợp đó, bạn có thể thử vứt bỏ() trên các đối tượng đó khi bạn hoàn thành việc sử dụng. – Kangkan

+0

@Kangkan - cho biết khi nào việc sử dụng kết thúc chính xác là vấn đề của tôi ... Thật dễ dàng để biết khi nào thế giới bản địa sắp kết thúc (quá trình tách rời, hình cầu d'tors vv) nhưng tại thời điểm đó, thế giới quản lý đã đã kết thúc. – eran

0

.NET Dll nên được coi là tập hợp các lớp ref riêng biệt. Mỗi thể hiện của lớp ref đều có tuổi thọ riêng của nó và việc quản lý tài nguyên được thực hiện tương đối với tuổi thọ của lớp. Mẫu Dispose được triển khai đúng cách giải quyết mọi vấn đề quản lý tài nguyên.

Mỗi lớp C++/CLI, trong đó có một số tài nguyên gốc hoặc thành viên lớp dùng một lần, phải có trình phá hủy và trình kết xuất tùy chọn. Cụ thể, các tham chiếu .NET được phát hành trong lớp hủy, được ánh xạ tới phương thức C# Dispose.

+0

Sự cố của tôi có thể là do sử dụng mẫu sai, nhưng tôi không thể tìm ra mẫu phù hợp. Hãy suy nghĩ về trường hợp của tôi như là một singleton bản địa, lưu trữ một tham chiếu đến một đối tượng .NET trong một auto_gcroot. Khi singleton bị hủy, auto_gcroot cố gắng giải phóng tham chiếu - nhưng đã quá muộn và kết quả là một sự cố. – eran

+1

Nếu bạn định giữ đối tượng miễn là tệp DLL của bạn được tải, chỉ cần "rò rỉ" tay cầm. Các bộ thu gom rác sẽ chăm sóc nó trong trường hợp cực kỳ không chắc rằng CLR vẫn chạy sau khi tải DLL của bạn. –

+0

Tôi đoán bạn giữ tham chiếu auto_gcroot đối với một số loại giao tiếp gọi lại từ một singleton gốc thành đối tượng .NET. Có lẽ tốt hơn là nên nghĩ về một thuật toán gọi lại khác, ví dụ, dựa trên các sự kiện gốc? –

2

Nếu bạn cần quản lý tải xuống của AppDomain, hãy sử dụng sự kiện AppDomain.DomainUnload để thực hiện việc dọn dẹp.

Như STW nói, các thư viện có mã được quản lý không bao giờ có thể được tách ra khỏi một AppDomain, cách duy nhất để tách nó ra khỏi quá trình của bạn là dỡ bỏ AppDomain.

Nếu bạn không quản lý AppDomains, chỉ cần rò rỉ tài nguyên được quản lý (và xả đúng tài nguyên không được quản lý trong quá trình tách riêng). Tốt hơn, hãy thiết kế nó như là phần mềm chỉ gặp sự cố để không cần dọn dẹp.

+0

DomainUnload có vẻ như một con đường hợp lệ và tôi mới bắt đầu khám phá nó, nhưng vẫn chưa thể làm cho nó hoạt động được. Vì bị rò rỉ các tài nguyên được quản lý, nó sẽ ổn, nhưng nó khó như vấn đề ban đầu ... để ngăn chặn chúng bị gc'ed, tôi phải có tham chiếu đến các đối tượng đó. Tôi rất muốn có thể phát hành những tài liệu tham khảo khi dỡ bỏ, nhưng điều này phải được thực hiện trong khi .NET vẫn còn xung quanh. Tìm ra đúng thời điểm chính xác là vấn đề của tôi ... – eran

+0

Bạn có thể ngăn không cho các đối tượng được thu thập bằng cách chỉ cần gọi 'GCHandle.Alloc'. Các tài nguyên sẽ kéo dài cho đến khi một cuộc gọi phù hợp với 'GCHandle.Free' hoặc appdomain được tải xuống. –

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