Làm thế nào để dỡ bỏ một DLL đã được tải bằng cách sử dụng DllImport
trong C#?Dỡ bỏ một DLL được tải bằng DllImport
Trả lời
Cách đáng tin cậy nhất để dỡ bỏ một DLL không được quản lý từ một quá trình được tải bởi một khai báo pinvoke [DllImport] là tự tải nó, một lần nữa, bằng cách ghim LoadLibrary(). Điều đó mang lại cho bạn một xử lý đáng tin cậy cho DLL và hoạt động chính xác ngay cả khi tên mô-đun của DLL không rõ ràng. Nó không có bất kỳ ảnh hưởng nào trong thời gian chạy, ngoài bộ nạp Windows làm tăng số lượng tham chiếu nội bộ trên DLL từ 1 đến 2.
Sau đó bạn có thể ghim FreeLibrary() hai lần để giảm số tham chiếu xuống 0, vượt qua nó IntPtr bạn nhận được từ LoadLibrary(). Điều đó unloads DLL, cũng như bất kỳ DLL phụ thuộc đã được nạp.
Ghi chú rằng bạn sẽ nhận được sự thất bại rất khó chịu khi bạn cố gắng PInvoke bất kỳ chức năng xuất khẩu trên DLL một lần nữa, bất kỳ thời gian sau khi làm điều này. Các marshaller pinvoke là không biết rằng DLL không phải là xung quanh nữa và sẽ gọi chức năng tại địa chỉ nó nghĩ là vẫn còn hợp lệ. Mà bom chương trình của bạn với một ngoại lệ AccessViolation nếu bạn may mắn. Hoặc chạy một bit hoàn toàn ngẫu nhiên của mã nếu bạn không quá may mắn và không gian địa chỉ trước đây bị chiếm đóng bởi DLL đã tái sử dụng bởi một DLL. Bất cứ điều gì có thể xảy ra sau đó, không ai trong số đó tốt.
Điều này sẽ miễn phí một mô-đun được tải trước đó khi bạn gọi hàm P/Gọi.
[DllImport("kernel32", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadModule(string moduleName)
{
foreach(ProcessModule mod in Process.GetCurrentProcess().Modules)
{
if(mod.ModuleName == moduleName)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Điều đó sẽ * thường * hoạt động. Nhưng tên mô-đun có thể không rõ ràng, nó có thể phát hành sai DLL. –
Hans là đúng. Vì vậy, có lẽ tốt hơn bằng cách sử dụng Path.GetFileName (mod.FileName) thay vì mod.ModuleName? – Peter
Hoặc treo vào con trỏ bạn nhận được từ LoadLibrary và so sánh BaseAddress với điều đó. – yoyo
Dựa trên Peters đề nghị này làm việc cho tôi:
[DllImport("kernel32", SetLastError = true)]
private static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadImportedDll(string DllPath)
{
foreach (System.Diagnostics.ProcessModule mod in System.Diagnostics.Process.GetCurrentProcess().Modules)
{
if (mod.FileName == DllPath)
{
FreeLibrary(mod.BaseAddress);
}
}
}
Kể từ khi tôi đi qua các thông tin ở đây trong khi tôi đang nhìn xung quanh để biết thông tin tôi con tôi sẽ đóng góp lại những gì tôi đã kết thúc làm để sửa chữa một vấn đề với Sixense SDK trên OSX IN UNITY. Bạn sẽ thấy trong đó một thực hiện tự động tải/dỡ một dylib trên OSX:
Chỉ trong trường hợp nếu bạn là fan hâm mộ của lập trình chức năng sau đó bạn có thể sử dụng LINQ để đạt được những gì @ IllidanS4 đã gợi ý:
[DllImport("kernel32", SetLastError=true)]
static extern bool FreeLibrary(IntPtr hModule);
public static void UnloadModule(string moduleName)
{
var loadedAssemblyModule =
Process.GetCurrentProcess().Modules.OfType<ProcessModule>()
.FirstOrDefault(x => x.ModuleName == moduleName);
if (loadedAssemblyModule != null)
FreeLibrary(loadedAssemblyModule.BaseAddress);
}
- 1. Buộc dỡ bỏ DLL khỏi assembly
- 2. Liệu một DLL có được loại bỏ nếu DLL nạp nó được dỡ xuống không?
- 3. Thuộc tính DllImport luôn tải DLL không được quản lý
- 4. Phát hiện khi một Mô-đun (DLL) được dỡ xuống
- 5. Dỡ một tập tin dll vào mef
- 6. Dỡ bỏ một module bằng Python
- 7. DllImport user32 vs user32.dll
- 8. Rcpp có thể gói DLL được dỡ bỏ mà không cần khởi động lại R?
- 9. Làm thế nào tôi có thể dỡ bỏ một DLL bằng cách sử dụng ctypes trong Python?
- 10. Dỡ bỏ bộ nạp lớp
- 11. Dỡ bỏ một ByteArray bằng cách sử dụng Actionscript 3
- 12. C++: dlclose không dỡ bỏ thư viện được chia sẻ
- 13. dỡ bỏ mã/mô-đun
- 14. Dỡ bỏ/Xóa nội dung khỏi iFrame
- 15. động "dỡ bỏ" một phác thảo Processing JS từ vải
- 16. C++: Vấn đề tải Dll
- 17. Làm thế nào để tự động tải & dỡ bỏ một TinyMCE Plugin
- 18. Nhúng dll không được quản lý vào một C# dll
- 19. Trang dỡ bỏ sự kiện trong asp.net
- 20. Dỡ bỏ một gói và tất cả các phụ thuộc
- 21. Tự động tải một DLL
- 22. [DllImport ("QCall")] là gì?
- 23. __declspec (dllimport) làm thế nào để tải thư viện
- 24. Asp.Net C# Vấn đề DllImport
- 25. C++ DLL không tải xuống với AppDomain
- 26. EEFileLoadException Khi tải C++ DLL trong DLL được quản lý
- 27. Đặt thuộc tính DllImport động
- 28. WinSxS không tải được VC++ DLL
- 29. C# - Đang tải NET hội vào AppDomain riêng biệt để bạn có thể dỡ bỏ Nó
- 30. .dll đã được tải trong một trình nạp lớp khác?
Nếu bạn định làm như vậy chỉ để tiết kiệm vài KB bộ nhớ in chân của mô-đun đã nạp thì nó không đáng giá. CLR tự làm như vậy bất cứ khi nào appDomain được tải xuống. Tôi sẽ tò mò muốn biết nếu bạn có một số lý do thực sự để thử dỡ dll bản địa. – RBT