COMException は、.NET Framework ベースのアプリケーションで WeakReference オブジェクトを作成するときに発生します

この記事は、Microsoft .NET Framework ベースのCOMExceptionアプリケーションで WeakReference オブジェクトを作成するときに発生する例外を回避するのに役立ちます。

元の製品バージョン:Microsoft .NET Framework 4.5
元の KB 番号: 2978463

現象

.NET Framework ベースのアプリケーションを開発することを想定しています。 このアプリケーションでは、リフレクション API を使用して、型のメソッドを WeakReference<T> 列挙します。 次に、 関数の GetFunctionPointer ハンドルで RuntimeMethodHandle メソッドを WeakReference<T>.Create 呼び出します。 メソッドへのポインターが、次の WeakReference<T>.Create コード サンプルのようなコードを使用して取得される場合:

var assembly = System.Reflection.Assembly.GetAssembly(typeof(WeakReference<object>));
foreach (Type t in assembly.GetTypes())
{
    if (t.Name.StartsWith("WeakReference") && t.IsGenericType)
    {
        MethodInfo[] methods = t.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance);
        foreach (MethodInfo method in methods)
        {
            if (method.Name != "Create")
            continue;
            var ptr = method.MethodHandle.GetFunctionPointer();
        }
    }
}

この状況では、次の COMException コード サンプルのようなオブジェクトを WeakReference<T> 作成すると、 が発生します。

WeakReference<object> wr = new WeakReference<object>(new object());

デバッガーがこのアプリケーションのプロセスにアタッチされている場合は、次のコード サンプルのような例外と呼び出し履歴を受け取ります。

例外オブジェクト: 0000000102b7bde8
例外の種類: System.Runtime.InteropServices.COMException
メッセージ: 指定されていないエラー (HRESULT からの例外: 0x80004005 (E_FAIL))
InnerException: <none>
StackTrace (生成):
<なし>
StackTraceString: <none>
HResult: 80004005

00 0081eb80 742d5ddf KERNELBASE!RaiseException+0x48
01 0081ec20 743eff3f clr!RaiseTheExceptionInternalOnly+0x27f
02 0081ec50 7445a27f clr!UnwindAndContinueRethrowHelperAfterCatch+0x90
03 0081ecb4 74132b0c clr!PreStubWorker+0x162
04 0081ece4 73a0fd37 clr!ThePreStub+0x16
05 0081ed08 0483039f mscorlib_ni!System.WeakReference1[[System.__Canon, mscorlib]]..ctor(System.__Canon)+0x7

回避策

この問題を回避するには、 メソッドへの WeakReference<T>.Create ポインターを取得しないでください。 このメソッドは クラスに WeakReference<T> 対してプライベートです。 そのため、このメソッドを呼び出すと、関数へのポインターを取得した場合でも、未定義の動作が発生する可能性があります。