4

以下は、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 上の Mono (v2.10.8.1) でまったく同じプログラムを試しました。少し有益ですが、まだ不可解な例外がありますGCHandle value belongs to a different domain.

私が知る限り、handle実際には、私が呼び出すコードと同じ AppDomain に属していますGCHandle.FromIntPtr。しかし、両方の実装で例外が見られるという事実は、いくつかの重要な詳細が欠けているのではないかと疑っています。何が起きてる?

4

2 に答える 2

6

AddrOfPinnedObjectの反対ではありませんFromIntPtr。代わりToIntPtrに:

IntPtr pointer = handle.ToIntPtr ();
GCHandle handle2 = GCHandle.FromIntPtr (pointer);

FromIntPtrはオブジェクトのアドレスを取得せず、不透明な値 (たまたま IntPtr として定義されている) を取得します。これは、ToIntPtr.

于 2013-06-26T23:45:45.257 に答える