CẬP NHẬT CHO .NET 4.0 VÀ NHIỀU KHUNG HÌNH GẦN ĐÂY
Đây là một câu hỏi cũ được đặt ra vào thời .Net 2.0, khi hỗ trợ cho các DLL ở chế độ hỗn hợp có vấn đề khởi tạo nghiêm trọng, dễ xảy ra tình trạng tắc nghẽn ngẫu nhiên. Kể từ .Net 4.0, việc khởi tạo các tệp DLL ở chế độ hỗn hợp đã thay đổi. Bây giờ có hai giai đoạn khởi tạo riêng biệt:
- Khởi tạo gốc, được gọi tại điểm vào của DLL, bao gồm thiết lập thời gian chạy C ++ gốc và thực thi phương thức DllMain của bạn.
- Khởi tạo được quản lý, được thực thi tự động bởi trình tải hệ thống.
Vì bước # 2 được thực hiện bên ngoài Khóa bộ tải nên không có bế tắc. Các chi tiết được mô tả tại Khởi tạo các lắp ráp hỗn hợp .
Để đảm bảo lắp ráp chế độ hỗn hợp của bạn có thể được tải từ một tệp thực thi gốc, điều duy nhất bạn cần kiểm tra là phương thức DllMain có được khai báo là mã gốc hay không. #pragma unmanaged
có thể giúp ở đây:
#pragma unmanaged
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
... // your implementation here
}
Điều quan trọng nữa là bất kỳ mã nào mà DllMain có thể gọi trực tiếp hoặc gián tiếp cũng không được quản lý. Bạn nên giới hạn loại chức năng được sử dụng bởi DllMain để bạn theo dõi tất cả mã có thể truy cập từ DllMain và đảm bảo rằng tất cả mã đều được biên dịch với#pragma unmanaged
.
Trình biên dịch giúp bạn một chút bằng cách cung cấp cho bạn C4747 nếu nó phát hiện ra rằng DllMain không được khai báo là không được quản lý:
1> Generating Code...
1>E:\src\mixedmodedll\dllmain.cpp : warning C4747: Calling managed 'DllMain': Managed code may not be run under loader lock, including the DLL entrypoint and calls reached from the DLL entrypoint
Tuy nhiên, trình biên dịch sẽ không tạo ra bất kỳ cảnh báo nào nếu DllMain gián tiếp gọi một số chức năng được quản lý khác, vì vậy bạn cần đảm bảo điều đó không bao giờ xảy ra, nếu không ứng dụng của bạn có thể bị deadlock ngẫu nhiên.