.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的数组,然后放到相应的位置上。



    本文转自Jake Lin博客园博客,原文链http://www.cnblogs.com/procoder/archive/2010/08/30/NET-Compact-Framework-aligment.html,如需转载请自行联系原作者

相关文章
|
6月前
|
关系型数据库 MySQL 数据库
找不到请求的 .Net Framework Data Provider。可能没有安装
做的一个项目,框架为.net framework 数据库为mysql 出现如标题错误 检查是否安装mysql、是否安装mysql connector net 笔者是因为没有安装后者mysql connector net 下载地址: [mysql connector net](https://downloads.mysql.com/archives/c-net/ "mysql connector net") 笔者安装截图如下: ![请在此添加图片描述](https://developer-private-1258344699.cos.ap-guangzhou.myqcloud.com/c
56 0
|
6月前
|
C# Windows
[记录]c#.net framework 4.5调用运行时库
[记录]c#.net framework 4.5调用运行时库
|
1月前
|
Windows
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
windows server 2019 安装NET Framework 3.5失败,提示:“安装一个或多个角色、角色服务或功能失败” 解决方案
|
6月前
|
Windows
​史上最详细的Windows10系统离线安装.NET Framework 3.5的方法(附离线安装包下载)
​史上最详细的Windows10系统离线安装.NET Framework 3.5的方法(附离线安装包下载)
552 0
|
4月前
|
C# Windows
C#安装“Windows 窗体应用(.NET Framework)”
C#安装“Windows 窗体应用(.NET Framework)”
51 0
|
7月前
|
开发框架 .NET 编译器
C#OOP之十四 .Net Framework简介
C#OOP之十四 .Net Framework简介
52 0
|
11月前
|
分布式计算 NoSQL Java
1..Net平台历程介绍和.net framework和netcore的架构体系对比,以及框架的选择介绍
1..Net平台历程介绍和.net framework和netcore的架构体系对比,以及框架的选择介绍
174 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
38 0
|
1月前
|
开发框架 前端开发 .NET
进入ASP .net mvc的世界
进入ASP .net mvc的世界
28 0