【发布时间】:2009-12-22 14:54:44
【问题描述】:
我遇到的问题也与 AppDomain 和 Windows 消息有关。
要在 Internet Explorer 中托管的网页,其中包含 .Net WinForms UserControl 派生控件 - HelloWorldCtl。此控件位于 C# 编写的程序集 - HelloWorldControl.dll 中。该控件使用来自另一个用 C++/CLR 编写的程序集的代码 - HelloWorldLibCPP.dll。
HelloWorldCtl 加载 HelloWorldLibCPP.dll 并调用将创建 Win32 本机窗口的代码并将该窗口放置在 HelloWorldCtl 的区域中。
导航到网页,HelloWorldCtl 加载,我可以看到它以及 HelloWorldCtl 区域中心的本机窗口。
C# 控件和本机窗口都有一些消息处理程序,并且消息都可以正常工作并到达 C# 控件的窗口和本机窗口;鼠标点击、重新绘制等等……但是,本机窗口的一些消息处理程序需要调用作为本机窗口父级的 C# 控件上的方法。这是使用 C# 控件实现的接口完成的,并且本机窗口通过将其存储在 GCHandle 中(来自 System::Runtime::InteropServices)来保存对它的引用。我为 GCHandle 使用了 gcroot 模板。
此时本机窗口中的代码尝试使用 GCHandle 调用 C# 控件上的任何方法时发生故障。 (c++ 代码使用 /clr 编译为托管代码。)
抛出的异常是:
“无法跨 AppDomain 传递 GCHandle”
我放了一些调试代码,在C#和本机窗口中显示CurrentDomain的Id和FriendName,我发现这些AppDomains不一样。
在原生窗口创建过程中,CurrentDomain与C#控件相同,但是当原生窗口接收消息并处理这些消息时,CurrentDomain与C#控件不同。
这种情况可以改变吗?是否可以让两个原生窗口消息处理程序在与 C# 控件相同的 AppDomain 中运行?
还有其他建议吗?
谢谢, 罗杰
【问题讨论】:
-
如果有人愿意回答,我会对回复感兴趣。