Tôi đang gói một DLL mở rộng MFC (MFCXDLL_2) để làm cho chức năng của nó có sẵn cho các lập trình viên C#.C# .NET Kiểm soát người dùng bên trong ứng dụng gốc. Các vấn đề về chuỗi tài nguyên
Trình bao bọc là "DLL thông thường sử dụng chia sẻ MFC DLL" với "Hỗ trợ thời gian chạy ngôn ngữ chung (/ clr)". (Chế độ hỗn hợp).
Các lớp trong MFCXDLL_2 sẽ có sẵn được trang trí bằng MFCXDLL_3.
Kịch bản mà tôi đang gặp phải là trường hợp MFCXDLL_2 được sử dụng từ điều khiển người dùng C# .NET chạy trong ứng dụng gốc.
Một phần mở rộng MFC DLL -MFCXDLL_1 khác bên trong ứng dụng gốc cũng sử dụng MFCXDLL_2 và điều này gây ra sự cố.
Khi tôi khởi động ứng dụng gốc, nó sẽ ngầm tải MFCXDLL_2.
Khi tôi tải điều khiển người dùng .NET, cùng một MFCXDLL_2 được tải lại một cách rõ ràng theo lời khuyên trong http://msdn.microsoft.com/en-us/library/ksa99t88.aspx, “Sử dụng cơ sở dữ liệu, OLE và ổ cắm DLL mở rộng trong DLL thông thường”.
Cả mã gốc và điều khiển người dùng .NET khởi tạo cùng loại lớp và gọi cùng một phương thức trong MFCXDLL_2.
Phương thức de-serializes dữ liệu (nhận được trên bộ nhớ dùng chung) và trả về dữ liệu đã được tuần tự hóa cho người gọi. Điều này làm việc tuyệt vời từ mã nguồn gốc cho đến khi tôi tải điều khiển người dùng .NET.
Sau khi tải điều khiển người dùng .NET, việc hủy tuần tự ngừng hoạt động từ mã gốc nhưng nó hoạt động tốt khi được gọi từ điều khiển người dùng .NET.
Tôi đã đính kèm WinDbg vào phiên bản gỡ lỗi của ứng dụng gốc và chạy kịch bản của tôi. WinDbg được tìm thấy như sau trong quá trình de-serialization:
“Cảnh báo: Không thể tải từ lưu trữ. Lớp không được xác định. Ngoại lệ giả mạo: badClass. ”
Tôi nghĩ rằng có một số vấn đề về tài nguyên ở đây vì vậy tôi chạy phiên bản phát hành của ứng dụng gốc tải phiên bản phát hành của MFCXDLL_2. Sau đó, tôi tải phiên bản gỡ lỗi của điều khiển người dùng .NET - một lần nữa tải phiên bản gỡ lỗi của MFCXDLL_2- vào ứng dụng gốc.
Sau đó, mọi thứ hoạt động tuyệt vời. Một phiên bản phát hành của MFCXDLL_2 được nạp bằng mã gốc và một phiên bản gỡ lỗi của MFCXDLL_2 được nạp bởi điều khiển người dùng .NET –tất cả đang chạy bên trong ứng dụng gốc.
Vậy điều gì đang xảy ra? Không thể truy cập cùng một MFCXDLL từ ví dụ một phần mở rộng DLL và một DLL thường xuyên cùng một lúc trong cùng một ứng dụng?
Chuỗi tài nguyên có bị phá hủy theo một cách nào đó không? Các giải pháp khả thi là gì?
Dưới đây là một số mã hiển thị MFCXDLL_2 DLL được nạp
cách Khi ứng dụng bản địa bắt đầu MFCXDLL_2 DllMain được gọi là:
static AFX_EXTENSION_MODULE MFCXDLL_2 = { NULL, NULL };
static CDynLinkLibrary* gpDynLinkLibrary = NULL;
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
// Extension DLL one-time initialization
AfxInitExtensionModule(MFCXDLL_2, hInstance);
// Insert this DLL into the resource chain
gpDynLinkLibrary = new CDynLinkLibrary(MFCXDLL_2);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Terminate the library before destructors are called
AfxTermExtensionModule(MFCXDLL_2);
}
return 1; // ok
}
Khi.điều khiển người dùng NET được nạp, các MFCXDLL_2 DLL được nạp một lần nữa:
//==============================================================
// Exported DLL initialization to run in context of Regular DLL.
// Must be called in InitInstance
// BOOL CYourRegularDLLApp::InitInstance()
//==============================================================
extern "C" _declspec(dllexport) CDynLinkLibrary* WINAPI InitMFCXDLL_2FromRegularDLL()
{
if (gpDynLinkLibrary)
{
delete gpDynLinkLibrary;
gpDynLinkLibrary = NULL;
}
// Create a new CDynLinkLibrary for this Regular DLL
return new CDynLinkLibrary(MFCXDLL_2);
}
Mã deserialize bên MFCXDLL_2
CMyClass* pMyclass = NULL; //CObject derived serializeable class
BYTE *pBuf = pGlobalCom->GetBuffer(); //Buffer with serialized CMyClass
int nBufSize = pGlobalCom->GetSize(); //Size of buffer
CMemFile mf;
mf.Attach(pBuf,nBufSize);
CArchive ar(&mf, CArchive::load); //“Warning: Cannot load CMyClass from archive. Class not defined.CArchive exception: badClass.”
ar >> pMyclass; //CArchive exception thrown
ar.Close();
mf.Detach();
Những hình ảnh cho thấy mối quan hệ giữa dlls.
Tôi có thể xem cách C# Wrapper giải quyết vấn đề. Làm cách nào để giải quyết sự cố? Tôi đang theo mẫu được đưa ra trong bài viết http://www.codeguru.com/cpp/cpp/cpp_managed/interop/article.php/c6867. Cầu nối thực tế giữa thế giới được quản lý và không được quản lý là DLL chế độ hỗn hợp. Trình bao bọc chỉ trang trí các lớp mà tôi muốn hiển thị cho điều khiển người dùng .NET. – kjella
Bạn nói đúng. Hình ảnh đã sai. Đó là tất nhiên là "thường xuyên dll sử dụng chia sẻ MFC DLL" đó là wrapper. Tôi đã thay đổi hình ảnh ngay bây giờ. Các MFCXDLL_3 trang trí một vài trong số các lớp học trong MFCXDLL_2 và làm cho chức năng cần thiết có sẵn cho người dùng kiểm soát. – kjella
Mẫu CodeGuru mà bạn đang xem là từ năm 2004. Tôi khá chắc chắn rằng nó không còn áp dụng (ít nhất là cho NET 3.5 trở đi). Tôi có thể kiểm tra lại bằng mã mà tôi có trên một máy khác và sẽ đăng lại sau. – ChrisBD