首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# StructLayout.Explicit问题

C# StructLayout.Explicit问题
EN

Stack Overflow用户
提问于 2009-07-25 19:05:28
回答 2查看 16.3K关注 0票数 11

我试图理解为什么下面的第二个示例没有问题,但是第一个示例给出了下面的例外。在我看来,这两个例子都应该根据描述给出一个例外。有人能指点我吗?

未处理异常: System.TypeLoadException:无法从程序集'StructTest、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null‘加载类型'StructTest.OuterType’,因为它包含一个偏移量为0的对象字段,该对象字段不正确地对齐或与非对象字段重叠。

在StructTest.Program.Main(String[] args)按任意键继续。。。

示例1

代码语言:javascript
运行
复制
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);
        }
    }
}

示例2

代码语言:javascript
运行
复制
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);
        }
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-07-25 19:24:56

公共语言运行库包含一个验证器,确保运行的代码(可验证的IL)不可能损坏托管环境中的内存。这将防止您声明字段重叠的结构。基本上,您的结构包含两个数据成员。一个整数(4个字节)和一个本机整数(指针大小)。在32位CLR (您可能正在运行代码)上,char[]将占用4个字节,因此,如果将整数与结构开头相距小于4个字节,则会有重叠字段。值得注意的是,在64位运行时,由于指针大小为8字节,这两个代码段都会失败。

票数 12
EN

Stack Overflow用户

发布于 2009-07-26 18:48:31

我想我应该用我用来创建工会的解决方案来回应--这是我的初衷。我使用了一个不安全的结构和一个固定的数组,然后使用一个属性与固定数组进行交互。我相信这能做我想做的事。

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;

namespace StructTest
{

    [StructLayout(LayoutKind.Explicit)]
    unsafe struct OuterType
    {
        private const int BUFFER_SIZE = 100;

        [FieldOffset(0)]
        private int transactionType;

        [FieldOffset(0)]
        private fixed byte writeBuffer[BUFFER_SIZE];

        public int TransactionType
        {
            get { return transactionType; }
            set { transactionType = value; }
        }

        public char[] WriteBuffer
        {
            set
            {
                char[] newBuffer = value;

                fixed (byte* b = writeBuffer)
                {
                    byte* bptr = b;
                    for (int i = 0; i < newBuffer.Length; i++)
                    {
                         *bptr++ = (byte) newBuffer[i];
                    }
                }
            }

            get
            {
                char[] newBuffer = new char[BUFFER_SIZE];

                fixed (byte* b = writeBuffer)
                {
                    byte* bptr = b;
                    for (int i = 0; i < newBuffer.Length; i++)
                    {
                        newBuffer[i] = (char) *bptr++;
                    }
                }

                return newBuffer;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            OuterType t = new OuterType();
            System.Console.WriteLine(t);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1182782

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档