首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Marshal从ushort数组C#读取结构

Marshal从ushort数组C#读取结构
EN

Stack Overflow用户
提问于 2021-01-25 13:22:40
回答 1查看 200关注 0票数 1

我试图从字节数组中读取结构:

代码语言:javascript
复制
var data = new ushort[10]{65535, 65535, 65535 ...};
var datashort = ChangeUshortToShort(data);
FromArray(datashort )

我的结构:

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class Failures
{
    public ushort cardTrErr;
    public uint TrErr;
    public uint KsrErr;
    public ushort sh6;
    public ushort sh12;
    public ushort blockade;
    public ushort biz;
    public ushort blockadeInPerm;

    public virtual byte[] ToArray()
    {
        int size = Marshal.SizeOf(this);
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.StructureToPtr(this, ptr, false);
        byte[] array = new byte[size];
        Marshal.Copy(ptr, array, 0, size);
        Marshal.FreeHGlobal(ptr);
        return array;
    }

    public virtual void FromArray(short[] val)
    {
        int size = Marshal.SizeOf(this);
        IntPtr ptr = Marshal.AllocHGlobal(size);
        Marshal.Copy(val.ToArray(), 0, ptr, size);
        Marshal.PtrToStructure(ptr, this);
        Marshal.FreeHGlobal(ptr);
    }
    public short[] ChangeUshortToShort(ushort[] val)
    {
        List<short> list = new List<short>();
        foreach (var item in val)
        {
            list.Add((short)(item & 0xFF));
            list.Add((short)(item >> 8));
        }
        return list.ToArray();
    }
}

方法ChangeUshortToShort返回具有所有值255的数组。

当我执行ToArray()时,它返回255。但是如果我这样做的话,FromArray()将为ushort分配255个值,而应该是65535。当应该是4294967295的时候,分配16711935。

我认为我应该使用MarshalAs的属性,但不知道如何使用。有人能帮我吗?

编辑:

第二结构:

代码语言:javascript
复制
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Flags
{
    public ushort frameCnt;
    public ushort progVersion;
    public byte algUM;
    public byte deviceNumber;
    public _alg_1U _alg_1U;
    public ushort OUTPUTS;
    public _statS _StatS1;
    public _statS2 _StatS2;
    //public ushort _StatS1;
    //public ushort _StatS2;
    public ushort nbLector;
    public ushort nbSignal;
    public byte comBlockadeT1;
    public byte comBlockadeT2;
    public _permS permS;
    //public ushort permS;
    public ushort permHistory;
    public ushort stopInfo;
    public _controlFlagsS _controlFlagsS;
    //public ushort _controlFlagsS;
    public ushort timerInfo;
    public ushort timerTrDiagCycle;
    public ushort sizeOfStruct;
    public ushort methanSensorValue1;
    public ushort methanSensorValue2;
    public ushort methanSensorValue3;
    public ushort methanSensorValue4;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _alg_1U
{
    public byte PZP1;
    public byte PZP2;
    public byte PZS;
    public byte PZZ1;
    public byte PZZ2;
    public byte PZZ3;
    public byte KB1;
    public byte KB2;
    public byte KRU;
    public byte reserved;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _statS
{
    public bool SYS_AW;
    public bool SYS_BK;
    public bool SYS_READY;
    public bool SYS_WORK;
    public bool PT_WORK;
    public bool DISPATCHER_ON_LINE;
    public bool SYS_STARTING;
    public bool LEKTOR_ERROR;
    public bool SYS_BK_KSR;
    public bool SYS_READY_LEKTOR;
    public bool SYS_INIT;
    public bool KRU_WORK;
    public bool SIG_RES_DIODA;
    public bool SIG_RES_BK_KSR;
    public bool SIG_RES_WORK;
    public bool unUse16;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _statS2
{
    public bool R1;
    public bool R2;
    public bool SAG_DISABLED;
    public bool unUse4;
    public bool unUse5;
    public bool unUse6;
    public bool unUse7;
    public bool unUse8;
    public bool unUse9;
    public bool unUse10;
    public bool unUse11;
    public bool unUse12;
    public bool unUse13;
    public bool unUse14;
    public bool unUse15;
    public bool unUse16;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _permS
{
    public bool PZP1;
    public bool PZP2;
    public bool PZS;
    public bool PZZ1;
    public bool PZZ2;
    public bool PZZ3;
    public bool KOMBAJN1;
    public bool KOMBAJN2;
    public bool KRU;
    public bool PT;
    public bool unUse11;
    public bool unUse12;
    public bool unUse13;
    public bool unUse14;
    public bool unUse15;
    public bool unUse16;
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct _controlFlagsS
{
    public bool confSaved;
    public bool confFrameErr;
    public bool confDataErr;
    public bool passSaved;
    public bool passFrameErr;
    public bool unUse6;
    public bool unUse7;
    public bool unUse8;
    public bool unUse9;
    public bool unUse10;
    public bool unUse11;
    public bool unUse12;
    public bool unUse13;
    public bool unUse14;
    public bool unUse15;
    public bool unUse16;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-25 13:30:45

如果您的意图是直接重新解释20个字节的数据,那么它们可能是很难完成的;请考虑:

代码语言:javascript
复制
using System;
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct Failures
{
    public ushort cardTrErr;
    public uint TrErr;
    public uint KsrErr;
    public ushort sh6;
    public ushort sh12;
    public ushort blockade;
    public ushort biz;
    public ushort blockadeInPerm;
}
static class P
{
    static void Main()
    {
        var data = new ushort[10];
        for (int i = 0; i < data.Length;i++) data[i] = 65535;

        // re-interpret
        Failures failures = MemoryMarshal.AsRef<Failures>(
            MemoryMarshal.Cast<ushort, byte>(data));
        // show the data
        Console.WriteLine(failures.cardTrErr);
        Console.WriteLine(failures.TrErr);
        Console.WriteLine(failures.KsrErr);
        Console.WriteLine(failures.sh6);
        Console.WriteLine(failures.sh12);
        Console.WriteLine(failures.blockade);
        Console.WriteLine(failures.biz);
        Console.WriteLine(failures.blockadeInPerm);
    }
}

然而,请注意,像这样重新解释强制转换是一场噩梦;至少做出一些CPU endianness断言是值得的(也就是说,如果数据是小的,那么如果您的CPU不是,抛出一个异常)。

如果您无法访问span,则可以通过unsafe实现相同的结果。

代码语言:javascript
复制
        Failures failures;
        unsafe
        {
            fixed (ushort* ptr = data)
            {   // re-interpret
                failures = *(Failures*)ptr;
            }
        }
        // show the data
        Console.WriteLine(failures.cardTrErr);
        Console.WriteLine(failures.TrErr);
        Console.WriteLine(failures.KsrErr);
        Console.WriteLine(failures.sh6);
        Console.WriteLine(failures.sh12);
        Console.WriteLine(failures.blockade);
        Console.WriteLine(failures.biz);
        Console.WriteLine(failures.blockadeInPerm);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65885606

复制
相关文章

相似问题

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