C#指向非托管结构的数组 [英] C# pointer to unmanaged struct with array

查看:703
本文介绍了C#指向非托管结构的数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



这是我要转换的字符串的结构:

  typedef struct 
{
UINT8 TrafficClass0:4;
UINT8版本:4;
UINT8 FlowLabel0:4;
UINT8 TrafficClass1:4;
UINT16 FlowLabel1;
UINT16长度;
UINT8 NextHdr;
UINT8 HopLimit;
UINT32 SrcAddr [4];
UINT32 DstAddr [4];
} DIVERT_IPV6HDR,* PDIVERT_IPV6HDR;

这里是我的C#结构:

  [StructLayoutAttribute(LayoutKind.Sequential)] 
public struct DivertIPv6Header
{
/// TrafficClass0:4
///版本:4
/// FlowLabel0:4
/// TrafficClass1:4
public uint bitvector1;

/// UINT16-> unsigned short
public ushort FlowLabel1;

/// UINT16-> unsigned short
public ushort长度;

/// UINT8-> unsigned char
public byte NextHdr;

/// UINT8-> unsigned char
public byte HopLimit;

/// UINT32 [4]
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 4,ArraySubType = UnmanagedType.U4)]
public uint [] SrcAddr;

/// UINT32 [4]
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 4,ArraySubType = UnmanagedType.U4)]
public uint [] DstAddr;

public uint TrafficClass0
{
get
{
return bitvector1& 15岁
}
set
{
bitvector1 = value | bitvector1;
}
}

public uint Version
{
get
{
return(bitvector1& 240u)/ 16;
}
set
{
bitvector1 =(value * 16)| bitvector1;
}
}

public uint FlowLabel0
{
get
{
return(bitvector1& 3840u)/ 256;
}
set
{
bitvector1 =(value * 256)| bitvector1;
}
}

public uint TrafficClass1
{
get
{
return(bitvector1& 61440u)/ 4096;
}
set
{
bitvector1 =(value * 4096)| bitvector1;
}
}
}

这里唯一的问题是我需要声明一个指向此结构的指针,以便我可以与它的数据重叠。



如果我尝试声明一个指针,我得到这个编译时错误: p>

 无法声明非非托管类型的指针。 

任何想法?

解决方案

使用 Marshal.PtrToStructure

  var bytes = yourUnmanagedByteArray; 

固定(byte * b = bytes)
return(T)Marshal.PtrToStructure(new IntPtr(b),typeof(DivertIPv6Header));

您可以使其无需固定缓冲区,如果你不想使用不安全的代码。


I am trying to implement a C style struct in C# for interoperability.

Here is the struct I'm string to convert:

typedef struct
{
    UINT8  TrafficClass0:4;
    UINT8  Version:4;
    UINT8  FlowLabel0:4;
    UINT8  TrafficClass1:4;
    UINT16 FlowLabel1;
    UINT16 Length;
    UINT8  NextHdr;
    UINT8  HopLimit;
    UINT32 SrcAddr[4];
    UINT32 DstAddr[4];
} DIVERT_IPV6HDR, *PDIVERT_IPV6HDR;

And here is my C# struct:

[StructLayoutAttribute(LayoutKind.Sequential)]
public struct DivertIPv6Header
{
    /// TrafficClass0 : 4
    /// Version : 4
    /// FlowLabel0 : 4
    /// TrafficClass1 : 4
    public uint bitvector1;

    /// UINT16->unsigned short
    public ushort FlowLabel1;

    /// UINT16->unsigned short
    public ushort Length;

    /// UINT8->unsigned char
    public byte NextHdr;

    /// UINT8->unsigned char
    public byte HopLimit;

    /// UINT32[4]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.U4)]
    public uint[] SrcAddr;

    /// UINT32[4]
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = UnmanagedType.U4)]
    public uint[] DstAddr;

    public uint TrafficClass0
    {
        get
        {
            return bitvector1 & 15u;
        }
        set
        {
            bitvector1 = value | bitvector1;
        }
    }

    public uint Version
    {
        get
        {
            return (bitvector1 & 240u) / 16;
        }
        set
        {
            bitvector1 = (value * 16) | bitvector1;
        }
    }

    public uint FlowLabel0
    {
        get
        {
            return (bitvector1 & 3840u) / 256;
        }
        set
        {
            bitvector1 = (value * 256) | bitvector1;
        }
    }

    public uint TrafficClass1
    {
        get
        {
            return (bitvector1 & 61440u) / 4096;
        }
        set
        {
            bitvector1 = (value * 4096) | bitvector1;
        }
    }
}

The only problem here is that I need to declare a pointer to this structure so that I can overlap with it's data.

If I try to declare a pointer I got this compile-time error:

cannot declare pointer to non-unmanaged type.

Any ideas?

解决方案

Use Marshal.PtrToStructure:

        var bytes = yourUnmanagedByteArray;

        fixed (byte* b = bytes)
            return (T)Marshal.PtrToStructure(new IntPtr(b), typeof(DivertIPv6Header));

You could make it work without a fixed buffer too, if you don't want to use unsafe code.

这篇关于C#指向非托管结构的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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