C#指向非托管结构的数组 [英] C# pointer to unmanaged struct with array
本文介绍了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屋!
查看全文