【问题标题】:Valid uses of raw pointers to arbitrary memory location in C#在 C# 中有效使用指向任意内存位置的原始指针
【发布时间】:2013-03-25 09:43:32
【问题描述】:

在以下代码中,我构建了一个指向位于任意内存位置的结构的指针:

[StructLayout(LayoutKind.Explicit)]
public struct S
{
    [FieldOffset(0)] int f0;
    [FieldOffset(4)] int f4;

    public static void Main() {
        unsafe {
            S* rawPtr = (S*)0x1234;
            rawPtr->f0 = 42;
        }
    }
}

如果我将f4 的类型更改为object 而不是int,则会收到错误Compiler Error CS0208: Cannot take the address of, get the size of, or declare a pointer to a managed type ('type')

struct S 上的哪些约束允许在 CIL(不仅仅是C#)级别上在该类型上构建指针?

This page on MSDNsbyte, byte, short, ushort, int, uint, long, ulong, char, char, @986 、decimalbool、枚举和指针是允许的,以及“用户定义的仅包含非托管类型字段的结构类型”,但没有指定非托管类型是什么。

【问题讨论】:

  • 巧合的是,非托管类型有sbytebyteshortushortintuintlongchar、@98764 987654352@、doubledecimalbool、枚举和指针。
  • @FrédéricHamidi 我有点猜到了,但我想从官方文档或 ECMA 335 标准中得到明确的声明。另外,我不确定该结构是否应该有StructLayout(LayoutKind.Explicit) 或类似的要求。

标签: c# pointers unmanaged unmanaged-memory


【解决方案1】:

我在网上找不到易于导航的 ECMA-335 版本,但 ECMA-334 paragraph 27.2 说:

unmanaged-type 是任何不是 reference-type 的类型, type-parameter,或通用 struct-type,并且不包含 type 不是 非托管类型。换句话说,非托管类型是 以下之一:

  • sbyte, byte, short, ushort, int, uint, long, ulong, @9876543331@, @98765430@, @9876434 decimal,或bool

  • 任何枚举类型

  • 任何指针类型

  • 仅包含 unmanaged-types 字段的任何非通用用户定义 struct-type

[注意:构造类型和类型参数永远不会 非托管类型结束说明]

结构的打包模式似乎与这种区别无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-29
    • 2015-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2016-12-08
    相关资源
    最近更新 更多