C#StructLayout.Explicit问题 [英] C# StructLayout.Explicit Question

查看:733
本文介绍了C#StructLayout.Explicit问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图理解为什么第二个例子下面没有问题的作品,但第一个例子中列出了我的异常。在我看来,在这两个例子应该给基础上,描述一个异常。任何人都可以告诉我吗?

  

未处理的异常:   System.TypeLoadException:无法   从负载类型StructTest.OuterType   集StructTest,版本= 1.0.0.0,   文化=中性公钥=空'   因为它包含的对象领域的   偏移0是正确对齐   或重叠由非对象字段。
  在StructTest.Program.Main(字符串[]   参数)preSS任意键继续。 。

示例1

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用了System.Runtime.InteropServices;
使用System.Text;

命名空间StructTest
{
    [StructLayout(LayoutKind.Sequential,包= 1)]
    结构InnerType
    {
        [的MarshalAs(UnmanagedType.ByValArray,SizeConst = 100)
        的char []缓冲区;
    }

    [StructLayout(LayoutKind.Explicit)
    结构OuterType
    {
        [FieldOffset(0)]
        INT someValue中;

        [FieldOffset(0)]
        InnerType someOtherValue;
    }

    类节目
    {
        静态无效的主要(字串[] args)
        {
            OuterType T =新OuterType();
            的System.Console.WriteLine(T);
        }
    }
}
 


例2

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用了System.Runtime.InteropServices;
使用System.Text;

命名空间StructTest
{
    [StructLayout(LayoutKind.Sequential,包= 1)]
    结构InnerType
    {
        [的MarshalAs(UnmanagedType.ByValArray,SizeConst = 100)
        的char []缓冲区;
    }

    [StructLayout(LayoutKind.Explicit)
    结构OuterType
    {
        [FieldOffset(4)]
        私人诠释someValue中;

        [FieldOffset(0)]
        InnerType someOtherValue;

    }

    类节目
    {
        静态无效的主要(字串[] args)
        {
            OuterType T =新OuterType();
            的System.Console.WriteLine(T);
        }
    }
}
 

解决方案

公共语言运行库包含了验证,使确保运行code(可验证IL)没可能破坏内存中的托管环境。这prevents你声明中域重叠的结构。基本上,你的结构包含两个数据成员。一个整数(这是4个字节)和一个本地整数(指针大小)。在32位CLR,在其中你可能运行您code时,的char [] 将需要4个字节,所以如果你把整数少于四个字节离开从结构的开始,你就会有重叠的领域。这是有趣的是,这两个与你的code片段无法在64位运行时,因为指针大小为8字节。

I'm trying to understand why the second example below works with no issues, but the first example gives me the exception below. It seems to me that both examples should give an exception based on the description. Can anyone enlighten me?

Unhandled Exception: System.TypeLoadException: Could not load type 'StructTest.OuterType' from assembly 'StructTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
at StructTest.Program.Main(String[] args) Press any key to continue . . .

Example 1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace StructTest
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct InnerType
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
        char[] buffer;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct OuterType
    {
        [FieldOffset(0)]
        int someValue;

        [FieldOffset(0)]
        InnerType someOtherValue;
    }

    class Program
    {
        static void Main(string[] args)
        {
            OuterType t = new OuterType();
            System.Console.WriteLine(t);
        }
    }
}


Example 2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace StructTest
{
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    struct InnerType
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
        char[] buffer;
    }

    [StructLayout(LayoutKind.Explicit)]
    struct OuterType
    {
        [FieldOffset(4)]
        private int someValue;

        [FieldOffset(0)]
        InnerType someOtherValue;

    }

    class Program
    {
        static void Main(string[] args)
        {
            OuterType t = new OuterType();
            System.Console.WriteLine(t);
        }
    }
}

解决方案

The common language runtime contains a verifier that makes sure the running code (verifiable IL) cannot possibly corrupt memory in the managed environment. This prevents you to declare such a structure in which fields overlap. Basically, your struct contains two data members. One integer (which is 4 bytes) and a native integer (pointer size). On a 32 bit CLR, in which you are probably running your code, the char[] will take 4 bytes so if you put the integer less than four bytes away from the beginning of the struct, you'll have overlapping fields. It's interesting to note that both of your code snippets with fail on a 64 bit runtime, as the pointer size is 8 bytes.

这篇关于C#StructLayout.Explicit问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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