首页 > 解决方案 > C++ 联合到 C# 工人阶级

问题描述

我只了解 C++ 中的联合是如何工作的。我认为我在 c# 类 mac_const 中复制了第一个注释块。(如果不是,请解释原因)我现在并不担心效率,只是它工作正常。第二个评论块我什至不知道从哪里开始翻译它。我不知道数据 [2] 映射到的位置,有人可以吗

//union {
//    unsigned short wd[4];
//    double data;
//    __int64 data64;
//}
//dbl_cnvt;

public class mac_const
{
    byte[] basedata = new byte[8];
    //public ushort[] wd
    public ushort this[byte index]
    {
        get { return BitConverter.ToUInt16(basedata, index * 2); }
        set { Array.Copy(BitConverter.GetBytes(value), 0, basedata, index * 2, 2); }
    }
    public double data
    {
        get { return BitConverter.ToDouble(basedata, 0); }
        set { basedata = BitConverter.GetBytes(value); }
    }
    public long data64
    {
        get { return BitConverter.ToInt64(basedata, 0); }
        set { basedata = BitConverter.GetBytes(value); }
    }
}


//union {
//    unsigned short cmd[4];
//    unsigned long data[2];
//    __int64 data64;
//}
//data_conversion;

public class data_conversion_csharp
{
    byte[] basedata = new byte[8];
    // the c++ class only 
    //public ushort[] cmd
    public ushort this[byte index]
    {
        get { return BitConverter.ToUInt16(basedata, index * 2); }
        set { Array.Copy(BitConverter.GetBytes(value), 0, basedata, index * 2, 2); }
    }
    public long[] data
    {
        // not sure what the mapping would be here, or if this should be data1 and data2 instead of an array
        ???
    }
    public long data64
    {
        ???
    }
}

编辑 - 关于联合 @ffhighwind 需要的解释我试图移植一些使用联合的 C++ 代码,因为它们应该是我不明白如何映射到第二个 long 数据

lng_cnvt.data64 = (dbl_cnvt.data64 >> 6) + (long)0x400000000000; 

if (data < 0)
{
    lng_cnvt.data64 = -lng_cnvt.data64;
    lng_cnvt.cmd[3] = 0;
    if (lng_cnvt.data64 == (__int64)0xC00000000000)
    {
        lng_cnvt.data64 = (__int64)0x800000000000; 
        exp -= 1;
    }
}
lng_cnvt.cmd[0] = (Ushort)((lng_cnvt.cmd[0] & 0xF000) | exp);
*ldata++ = lng_cnvt.ldata[0] & 0xFFFFFFL;
*ldata++ = ((lng_cnvt.data[0] >> 24) & 0x000FFL) |                                          
    ((lng_cnvt.data[1] << 8) & 0x0FFFF00L);

标签: c#c++union

解决方案


我没有投反对票,但没有 50 多个代表我无法发表评论,所以也许其他人在同一条船上。这样做的目的是什么,为什么你不能直接投反对票?

也许您想限制对象可以包含的类型。如果是这样,会这样做吗?

class MyUnion
{
   object obj;

   MyUnion(SomeType o) { obj = o; }
   //... constructors for all accepted Types

   public object Value { get { return obj; } }
}

C# 是托管的,因此您不能真正期望对数据进行微调的低级控制。如果您想要像 C++ 这样的微调控件,您将需要sizeofunmanaged unsafe code

编辑:显然你可以使用乔纳森蔡斯所说的属性来建立工会。


推荐阅读