固定大小的缓冲区不能直接从所用,;这"目的 [英] Fixed size buffer cannot be directly used from "this" object

查看:384
本文介绍了固定大小的缓冲区不能直接从所用,;这"目的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用的结构来表示纯数据。其中一个字段是一个固定大小的缓冲区,如下图所示。

I am used a structure to represent pure data. One of the fields is a fixed-size buffer, as shown below.

[StructLayout(LayoutKind.Sequential, Pack=2)]
unsafe struct ImageDosHeader
{
    ...
    private fixed ushort _e_res[4];
    ...

    [Description("Reserved")]
    [DisplayName("e_res[0]")]
    public ushort e_res_0 { get { ... } set { ... } }

    ...
}

在get / set函数我试着做以下,但我得到编译器错误CS1666:你不能使用包含在不固定的表情固定大小的缓冲区尝试使用固定的语句

Within the get/set functions I tried to do the following but I get "Compiler Error CS1666: You cannot use fixed size buffers contained in unfixed expressions. Try using the fixed statement."

return this._e_res[0];



但是,下面的工作:

However, the following work:

fixed (ImageDosHeader* p = &this)
    return p->_e_res[0];

ImageDosHeader local = this;
return local._e_res[0];



我可以轻松地使用了解决方法,但是,我想知道为什么直接访问从固定大小的缓冲区这是非法的。或者,这是我应该报告?

I can easily use the workarounds, however, I am wondering why directly accessing the fixed-size buffer from this is illegal. Or is this a bug that I should report?

我使用.NET 2.0中的错误。

I am using .NET 2.0.

推荐答案

这是因为底层的IL指令

It's because of the underlying IL instructions.

该程序的指令序列,以获得您想要的元素:

The program does this sequence of instructions to get the element you want:


  1. 加载地址压入堆栈。

  1. Load the address onto the stack.

加载偏移到堆栈

添加他们。

读取该内存地址的值。

如果对象是在堆中,然后第4步之前将因为垃圾收集,然后将地址从第1步装将不再有效。为了防止这一点,你需要首先钉住对象到内存中。

If the object is in the heap and then moves because of garbage collection before step 4, then the address loaded from step 1 will no longer be valid. To protect against this, you need to pin the object into memory first.

(你正在访问通过此结构的事实指针意味着,你不知道,如果结构上堆或堆栈上,所以你必须用别针把它以防万一它是在堆上。)

(The fact that you're accessing the structure through the this pointer means that you have no idea if the structure is on the heap or on the stack, so you have to pin it just in case it's on the heap.)

第二个例子工程,因为它的拷贝的结构,转的的,所以拷贝不能走动,所以该地址始终有效。

The second example works because it copies the structure to the stack, and so the copy can never move around, so the address will always be valid.

为什么没有同样的问题发生与其他类型的领域?由于他们的偏移量是已知的编译时间的,而数组索引是在众所周知的运行时的,因此JIT可以生成代码,将永远正确访问的字段。

Why doesn't the same issue happen with other kinds of fields? Because their offset is known at compile-time, whereas the array index is known at run-time, so the JIT can generate code that will always access the fields correctly.

这篇关于固定大小的缓冲区不能直接从所用,;这"目的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆