这是一个非常简单(完整)的程序,用于练习 GCHandle.FromIntPointer 的使用:
using System;
using System.Runtime.InteropServices;
namespace GCHandleBugTest
{
class Program
{
static void Main(string[] args)
{
int[] arr = new int[10];
GCHandle handle = GCHandle.Alloc(arr, GCHandleType.Pinned);
IntPtr pointer = handle.AddrOfPinnedObject();
GCHandle handle2 = GCHandle.FromIntPtr(pointer);
}
}
}
请注意,此程序本质上是第 547 页通过 C# (4e) 在 CLR 上用英语描述的过程的音译。但是,运行它会导致非托管异常,例如:
Additional Information: The runtime has encountered a fatal error. The address of the error was at 0x210bc39b, on thread 0x21bc. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack.
认为这可能是 .NET 4.5 中的一个错误,并且由于我没有发现任何明显错误,我在 Linux (v2.10.8.1) 上的 Mono 中尝试了完全相同的程序。我得到了更多信息但仍然令人费解的例外GCHandle value belongs to a different domain.
据我所知,handle
确实与我调用的代码属于同一个 AppDomain GCHandle.FromIntPtr
。但是,我在两种实现中都看到了异常,这让我怀疑我遗漏了一些重要的细节。这里发生了什么?