C#中要转一个C++中union套struct的联合体,求指点啊!

时间:2022-09-05 17:59:22
C++ code
struct{
    unsigned int ia;
}A;
struct{
    unsigned int ib;
}B;
union{
    A a;
    B b;
}U;
转成C#中的:
[StructLayout(LayoutKind.Sequential)]
public struct A{
    public UInt32 ia;
};
[StructLayout(LayoutKind.Sequential)]
public struct B{
    public UInt32 ib;
};
[StructLayout(LayoutKind.Explicit)]
public struct U{
    [FieldOffset(0)]
    public A a;
    [FieldOffset(0)]
    public B b;
};
会报错
 An unhandled exception of type 'System.TypeLoadException' occurred in Debugger.exe
 Additional information: 未能从程序 集 Debugger, Version=1.0.1572.568, Culture=neutral, PublicKeyToken=null 中 加载类型 U,因为它在 0偏移位置处包含一个对象字段,该字段已由一个非对象字段不正确地对齐或重叠。
//////////
但是,如果把A,B改成如下就能运行正常。

[StructLayout(LayoutKind.Sequential)]
public struct A{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    public UInt32[] ia;
};
[StructLayout(LayoutKind.Sequential)]
public struct B{
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
    public UInt32[] ib;
};
但不知道能否达到相同的union效果……,请问我刚开始该怎么转才能实现union套struct的功能啊!!跪谢!

10 个解决方案

#1



[StructLayout(LayoutKind.Explicit)]
public struct U{
    [FieldOffset(0)]
    public A a;
    [FieldOffset(1)]
    public B b;
};

#2


两个字段都是偏移0了

#3


使用属性访问器代替重叠的元素。
比如
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    struct Integer
    {
        public uint Value;
        public ushort High
        {
            get { return Convert.ToUInt16(Value / 0x10000); }
            set { Value = (uint)value * 0x10000 + Low; }
        }
        public ushort Low
        {
            get { return Convert.ToUInt16(Value % 0x10000); }
            set { Value = (uint)High * 0x10000 + value; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Integer i;
            i.Value = 0x87654321;
            Console.WriteLine("H: {0:x}, L: {1:x}", i.High, i.Low);
            i.Low = 0x5678;
            i.High = 0x1234;
            Console.WriteLine("{0:x}", i.Value);
        }
    }
}

#4


当然你也可以反过来写:
把Value作为属性,High和Low作为字段,总之重叠元素的一方作为属性访问器。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    struct Integer
    {
        public ushort High;
        public ushort Low;
        public uint Value
        {
            get { return (uint)High * 0x10000 + Low; }
            set { High = Convert.ToUInt16(value / 0x10000); Low = Convert.ToUInt16(value % 0x10000); }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Integer i = new Integer();
            i.Value = 0x87654321;
            Console.WriteLine("H: {0:x}, L: {1:x}", i.High, i.Low);
            i.Low = 0x5678;
            i.High = 0x1234;
            Console.WriteLine("{0:x}", i.Value);
        }
    }
}

#5


关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应

#6


引用 5 楼 hdt 的回复:
关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应

-----------------------------------------------------
如果每个union对应多个struct,那我的参数就变成了多种了
C#支持一个函数名多种参数的复用么?
谢谢啦!!

#8


引用 6 楼 yexianzhao 的回复:
引用 5 楼 hdt 的回复:关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应
-----------------------------------------------------
如果每个union对应多个struct,那我的参数就变成了多种了
C#支持一个函数名多种参数的复用么?
谢谢啦!!
       ……


所以用我的方法比较好。见仁见智的事情,事实上因为C#有属性,所以不需要什么联合体这种东西了。

#9


如果union 下面的各个字段结构相同,上边所有的方法都可以,
但话说回来了,如果各个字段都相同的话,何必用union???

#10


衷心的感谢hdt与caozhy版主的热心答复与指导!由于我的Union中包含的结构太过复杂,选用了hdt的解决方案。最近工作较忙,这么久才结贴,万分抱歉。

#1



[StructLayout(LayoutKind.Explicit)]
public struct U{
    [FieldOffset(0)]
    public A a;
    [FieldOffset(1)]
    public B b;
};

#2


两个字段都是偏移0了

#3


使用属性访问器代替重叠的元素。
比如
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    struct Integer
    {
        public uint Value;
        public ushort High
        {
            get { return Convert.ToUInt16(Value / 0x10000); }
            set { Value = (uint)value * 0x10000 + Low; }
        }
        public ushort Low
        {
            get { return Convert.ToUInt16(Value % 0x10000); }
            set { Value = (uint)High * 0x10000 + value; }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Integer i;
            i.Value = 0x87654321;
            Console.WriteLine("H: {0:x}, L: {1:x}", i.High, i.Low);
            i.Low = 0x5678;
            i.High = 0x1234;
            Console.WriteLine("{0:x}", i.Value);
        }
    }
}

#4


当然你也可以反过来写:
把Value作为属性,High和Low作为字段,总之重叠元素的一方作为属性访问器。
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    struct Integer
    {
        public ushort High;
        public ushort Low;
        public uint Value
        {
            get { return (uint)High * 0x10000 + Low; }
            set { High = Convert.ToUInt16(value / 0x10000); Low = Convert.ToUInt16(value % 0x10000); }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Integer i = new Integer();
            i.Value = 0x87654321;
            Console.WriteLine("H: {0:x}, L: {1:x}", i.High, i.Low);
            i.Low = 0x5678;
            i.High = 0x1234;
            Console.WriteLine("{0:x}", i.Value);
        }
    }
}

#5


关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应

#6


引用 5 楼 hdt 的回复:
关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应

-----------------------------------------------------
如果每个union对应多个struct,那我的参数就变成了多种了
C#支持一个函数名多种参数的复用么?
谢谢啦!!

#7


#8


引用 6 楼 yexianzhao 的回复:
引用 5 楼 hdt 的回复:关于Union封送,msdn有详细的解释,
大致是关于那个union 写两个struct 对应
-----------------------------------------------------
如果每个union对应多个struct,那我的参数就变成了多种了
C#支持一个函数名多种参数的复用么?
谢谢啦!!
       ……


所以用我的方法比较好。见仁见智的事情,事实上因为C#有属性,所以不需要什么联合体这种东西了。

#9


如果union 下面的各个字段结构相同,上边所有的方法都可以,
但话说回来了,如果各个字段都相同的话,何必用union???

#10


衷心的感谢hdt与caozhy版主的热心答复与指导!由于我的Union中包含的结构太过复杂,选用了hdt的解决方案。最近工作较忙,这么久才结贴,万分抱歉。