Windows PowerShell、その他の動的言語、および動的に実行される C# コードで、.NET Framework を対象とするコードが一部のメソッドを呼び出すときに例外が発生する

適用先
Windows Vista Service Pack 2 Windows 7 Service Pack 1 Windows Server 2008 Service Pack 2 Windows Server 2008 R2 Service Pack 1 Windows 8 Windows Server 2012 Datacenter Windows Server 2012 Datacenter Windows Server 2012 Essentials Windows Server 2012 Foundation Windows Server 2012 Foundation Windows Server 2012 Standard Windows Server 2012 Standard Windows Server 2012 R2 Datacenter Windows Server 2012 R2 Essentials Windows Server 2012 R2 Foundation Windows Server 2012 R2 Standard Windows 8.1

現象

Microsoft .NET Framework 4.5.1 または Microsoft ..NET Framework 4.5.2 をターゲットとするコードで、コードがメソッドに動的にバインドされる場合 (たとえば、Windows PowerShell、IronPython、IronRuby、またはその他の動的言語のスクリプトを使用して)、System.Runtime.InteropServices.Marshal.SizeOf メソッドまたはSystem.Runtime.InteropServices.Marshal.PtrToStructure メソッドを作成する場合は、次の問題が発生する可能性があります。

注: そのコードが C# の動的キーワード (keyword)を使用しない限り、既にマネージ実行可能ファイルにコンパイルされているコードでは、これらの問題は発生しません。

問題 1

System.Runtime.InteropServices.Marshal.SizeOf を呼び出すと、次の MethodInvocationException 例外がスローされます。

注

型 '<Type name>' は、アンマネージド構造体としてマーシャリングできません。意味のあるサイズまたはオフセットを計算できません。

問題 2

System.Runtime.InteropServices.Marshal.PtrToStructure を呼び出すと、次の MethodInvocationException 例外がスローされます。

注

指定する構造体は、blitable であるか、レイアウト情報を持っている必要があります。

          

問題 3

System.Runtime.InteropServices.Marshal.PtrToStructure を呼び出すと、次の RuntimeBinderException 例外がスローされます。

注

型 'void' を 'object' に暗黙的に変換することはできません。

          

原因

この問題は、スクリプト エンジンと動的言語が .NET Framework に導入された新しいオーバーロードにバインドする可能性があるために発生します。 具体的には、Marshal.SizeOf(Type) を使用していた呼び出しは Marshal.SizeOf<T>(T) を呼び出すようになり、Marshal.PtrToStructure(IntPtr, Type) を使用していた呼び出しは Marshal.PtrToStructure<T>(IntPtr, T) を呼び出すことができるようになりました。 この変更により、メソッドまたはランタイム バインダーが例外をスローします。

回避策

この問題を回避するには、言語で可能な場合は正しいオーバーロードが使用されるようにコードを変更します。 特定のメソッド オーバーロードを指定できない場合は、代わりに新しいメソッド オーバーロードが正しく使用されるようにコードを変更します。

C# 動的呼び出しの場合

メソッド SizeOf またはメソッド PtrToStructure の呼び出し内で、System.Type にキャストを追加します。 次に例を示します。

object obj = System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, (System.Type)type);
int size = System.Runtime.InteropServices.Marshal.SizeOf((System.Type)type);

注: これは、メソッドの引数の 1 つが動的である場合にのみ必要です。

Windows PowerShell スクリプトの場合

メソッド SizeOf またはメソッド PtrToStructure の呼び出し内で、System.Type にキャストを追加します。 次に例を示します。

$size = [System.Runtime.InteropServices.Marshal]::SizeOf([System.Type] $type)

$obj = [System.Runtime.InteropServices.Marshal]::PtrToStructure($ptr, [System.Type] $type)

IronPython スクリプトの場合

型の新しい型インスタンスを作成し、新しいメソッド オーバーロードを使用します。 次に例を示します。

typeInstance = type()

size = System.Runtime.InteropServices.Marshal.SizeOf(typeInstance)

obj = System.Runtime.InteropServices.Marshal.PtrToStructure(ptr, typeInstance)

状態

Microsoft は、これが "適用対象" セクションに記載されている Microsoft 製品の問題であることを確認しました。

参考資料