繁体   English   中英

为什么尝试的 Union 结构会导致 System.ExecutionEngineException?

[英]Why does attempted Union structure cause System.ExecutionEngineException?

我尝试使用下面的代码尝试 .NET 支持联合的能力,但它会导致 .NET 2.0 中的 System.ExecutionengineException 和 .NET 4 中的 FatalExecutionEngineError 。

运行时遇到致命错误。 错误地址位于线程 0x1080 上的 0x738b3138。 错误代码为 0xc0000005。 此错误可能是 CLR 中的错误或用户代码的不安全或不可验证部分中的错误。 此错误的常见来源包括 COM 互操作或 PInvoke 的用户封送错误,这可能会损坏堆栈。

我同意这段代码不应该工作,但我没想到会出现这种异常。 这是 .NET 错误吗?

Class POLine
  Public price As Decimal
  Public VendorItem As String
End Class

Class SOLine
  Public price As Decimal
  Public Required As DateTime
End Class

<System.Runtime.InteropServices.StructLayout(System.Runtime.InteropServices.LayoutKind.Explicit)> _
Structure LineRef
  <System.Runtime.InteropServices.FieldOffset(0)> _
  Public poLine As POLine
  <System.Runtime.InteropServices.FieldOffset(0)> _
  Public soLine As SOLine
End Structure

Sub Main()
  Dim lr As New LineRef
  lr.poLine = New POLine With {.price = 1.23D, .VendorItem = "X22"}
  lr.soLine = New SOLine With {.price = 3.14D, .Required = DateTime.Now}
  Console.WriteLine("{0} {1}", lr.soLine.price, lr.soLine.Required)
  Console.WriteLine("{0} {1}", lr.poLine.price, lr.poLine.VendorItem)
End Sub

您的代码无法验证,因为 object 引用不应重叠,您的poLinesoLine字段显然会重叠。 正如ECMA CLI 规范第 2 部分第 10.7 节所述:

偏移值应为非负数。 可以以这种方式重叠字段,尽管 object 引用占用的偏移量不应与内置值类型或另一个 object 引用的一部分占用的偏移量重叠。 虽然一个 object 参考可以与另一个完全重叠,但这是无法验证的。

您可以使用 PEVerify 进一步检查您的代码是否无法验证(从 Visual Studio 命令提示符对您的可执行文件运行 peverify.exe)——它将确认代码包含错误。

因此,您在运行时看到异常并不奇怪,而且您看到的异常对我来说似乎完全合理(文本表明它可能是由无法验证的代码引起的) - 是什么导致您期望不同的行为?

将第二个字段偏移量更改为 80(或更高)将解决您的问题。

虽然我不知道所有的结构布局和偏移量是什么,但您甚至将它们用于什么?

编辑:哦,刚刚注意到你的问题是为什么它会给出这个错误而不是导致它的原因,并且 4.0 网络说该错误可能是由损坏堆栈引起的,并且你声明了一个与第一个相同偏移量的变量...... . 破坏堆栈。 该错误没有问题。

您将两种引用类型映射到相同的偏移量。 只要您不尝试同时使用两者,这本身并不违法,这正是您在这里尝试做的。

这不是错误,您对 union 的使用完全是错误的,系统理所当然地抱怨。 在本机环境中,指针会被默默地覆盖。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM