快捷搜索:

.NET Compact Framework结构体的对齐问题

应用.NET Compact Framework进行P/Invoke或者必要解析异构系统的数据时,必要筹备布局体。如下:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

internal struct TestStruct

{

[MarshalAs(UnmanagedType.R8)]

public double f1;

}

在.NET Framework StructLayoutAttribute包孕了一个Pack属性,可以指定对齐,可是在.NET Compact Framework去掉落了这个属性,所有没有法子知道对齐要领的,在ARM平台下,默认的对齐为4.别的一个可能的办理规划是应用TypeAttributes.ExplicitLayout,入下图,在.NET Framework,下面的布局体的长度是10,可是在.NET Compact Framework长度是12,为什么呢?

[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Auto)]

internal struct TestStruct

{

[FieldOffset(0)]

public byte b1;

[FieldOffset(1)]

public byte b1;

[FieldOffset(2)]

public double f1;

}

看源码能找到缘故原由,下面是.NET Compact Framework 2.0 StructLayoutAttribute的源代码

[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false)]

public sealed class StructLayoutAttribute : Attribute

{

// Fields

public CharSet CharSet;

public int Size;

// Methods

public StructLayoutAttribute(LayoutKind layoutKind)

{

}

}

下面是.NET Framework 4.0 StructLayoutAttribute的源码

[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false), ComVisible(true)]

public sealed class StructLayoutAttribute : Attribute

{

// Fields

internal LayoutKind _val;

public CharSet CharSet;

private const int DEFAULT_PACKING_SIZE = 8;

public int Pack;

public int Size;

// Methods

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]

public StructLayoutAttribute(short layoutKind)

{

this._val = (LayoutKind)layoutKind;

}

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]

public StructLayoutAttribute(LayoutKind layoutKind)

{

this._val = layoutKind;

}

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]

internal StructLayoutAttribute(LayoutKind layoutKind, int pack, int size, CharSet charSet)

{

this._val = layoutKind;

this.Pack = pack;

this.Size = size;

this.CharSet = charSet;

}

[SecurityCritical]

internal static Attribute GetCustomAttribute(RuntimeType type)

{

if (!IsDefined(type))

{

return null;

}

int packSize = 0;

int classSize = 0;

LayoutKind auto = LayoutKind.Auto;

switch ((type.Attributes & TypeAttributes.LayoutMask))

{

case TypeAttributes.AutoLayout:

auto = LayoutKind.Auto;

break;

case TypeAttributes.SequentialLayout:

auto = LayoutKind.Sequential;

break;

case TypeAttributes.ExplicitLayout:

auto = LayoutKind.Explicit;

break;

}

CharSet none = CharSet.None;

TypeAttributes attributes2 = type.Attributes & TypeAttributes.CustomFormatClass;

if (attributes2 == TypeAttributes.AutoLayout)

{

none = CharSet.Ansi;

}

else if (attributes2 == TypeAttributes.UnicodeClass)

{

none = CharSet.Unicode;

}

else if (attributes2 == TypeAttributes.AutoClass)

{

none = CharSet.Auto;

}

type.GetRuntimeModule().MetadataImport.GetClassLayout(type.MetadataToken, out packSize, out classSize);

if (packSize == 0)

{

packSize = 8;

}

return new StructLayoutAttribute(auto, packSize, classSize, none);

}

internal static bool IsDefined(RuntimeType type)

{

return ((!type.IsInterface && !type.HasElementType) && !type.IsGenericParameter);

}

// Properties

public LayoutKind Value

{

[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]

get

{

return this._val;

}

}

}

在.NET Compact Framework完全没有实现StructLayoutAttribute ,所有不管应用LayoutKind.Sequential照样LayoutKind.Explicit默认照样应用Sequential。以是假如在.NET Compact Framework解析异构系统的布局体,只能应用byte[]一点点手工解析了。换句话说便是把int,float等数据类型转换成byte的数组,然后放到响应的位置上。

转自:http://www.cnblogs.com/procoder/archive/2010/08/30/NET-Compact-Framework-aligment.html

您可能还会对下面的文章感兴趣: