.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,如需转载请自行联系原作者

相关文章
|
2月前
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
使用的是.NET Framework 4.0,并且需要使用SMTP协议发送电子邮件
56 1
|
2月前
|
开发框架 缓存 监控
NET Framework 到 .NET 5/6 的迁移是重大的升级
本文详细介绍了从 .NET Framework 4.8 迁移到 .NET 5/6 的过程,通过具体案例分析了迁移策略与最佳实践,包括技术栈评估、代码迁移、依赖项更新及数据库访问层的调整,强调了分阶段迁移、保持代码可维护性及性能监控的重要性。
61 3
|
2月前
|
机器学习/深度学习 编解码 算法
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
《nnU-Net: 自适应框架用于基于U-Net的医学图像分割》是一篇2018年的论文,发表在Nature上。该研究提出了一种自适应的医学图像分割框架nnU-Net,能够自动调整模型的超参数以适应不同的数据集。通过2D和3D U-Net及级联U-Net的组合,nnU-Net在10个医学分割数据集上取得了卓越的性能,无需手动调整。该方法强调数据增强、预处理和训练策略等技巧,为医学图像分割提供了一个强大的解决方案。
97 0
【小样本图像分割-4】nnU-Net: Self-adapting Framework for U-Net-Based Medical Image Segmentation
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
本文讨论了在基于.NET 6和.NET Framework的WinForms项目中添加图表控件的不同方法。由于.NET 6的WinForms项目默认不包含Chart控件,可以通过NuGet包管理器安装如ScottPlot等图表插件。而对于基于.NET Framework的WinForms项目,Chart控件是默认存在的,也可以通过NuGet安装额外的图表插件,例如LiveCharts。文中提供了通过NuGet添加图表控件的步骤和截图说明。
winform .net6 和 framework 的图表控件,为啥项目中不存在chart控件,该如何解决?
|
4月前
|
开发框架 缓存 前端开发
实战.NET Framework 迁移到 .NET 5/6
从.NET Framework 迁移到.NET 5/6 是一次重要的技术革新,涵盖开发环境与应用架构的全面升级。本文通过具体案例详细解析迁移流程,包括评估现有应用、利用.NET Portability Analyzer 工具识别可移植代码、创建新项目、逐步迁移代码及处理依赖项更新等关键步骤。特别关注命名空间调整、JSON 序列化工具更换及数据库访问层重构等内容,旨在帮助开发者掌握最佳实践,确保迁移过程平稳高效,同时提升应用性能与可维护性。
151 2
NET Framework安装失败的麻烦
本人机子环境是安装了VS2012,即安装了 .NET Framework4.5,现在要安装AutoCAD2013,而安装CAD2013需要安装4.0的Framework,由于本机已有高版本的Framework,安装自然报错: 又不想来卸载4.5,觉得麻烦,但又想装上CAD2013,唯一的方法是修改Setup.ini初始化文件。
1068 0
|
3月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
48 7
|
3月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
77 0
|
4月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
56 0
|
4月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?