症状
当面向 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# 中使用dynamic关键字。问题 1
对System.Runtime.InteropServices.Marshal.SizeOf的调用引发MethodInvocationException以下异常︰
不能将 <类型名称> 类型封送为非托管结构;可以计算出任何有意义的大小或偏移量。
问题 2
对System.Runtime.InteropServices.Marshal.PtrToStructure的调用引发MethodInvocationException以下异常︰
指定的结构必须是本机或具有布局信息。
问题 3
对System.Runtime.InteropServices.Marshal.PtrToStructure的调用引发RuntimeBinderException以下异常︰
无法隐式转换为对象的 void 类型。
原因
出现此问题是因为脚本引擎并动态语言可能会绑定到.NET Framework 中引入的新重载。特别是,以前使用Marshal.SizeOf(Type)的调用可能会立即调用Marshal.SizeOf < T > (T),并使用Marshal.PtrToStructure (IntPtr,类型)的调用可能会立即调用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);
注意:这才需要动态方法的参数之一时。
对于 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 产品中的问题。