博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题
阅读量:5237 次
发布时间:2019-06-14

本文共 1002 字,大约阅读时间需要 3 分钟。

1. 使用场景

公共语言运行时控制数据字段的类或结构在托管内存中的物理布局。但是,如果想要将类型传递到非托管代码,需要使用 StructLayout 属性。

 

2. 内存分配问题。

如果不显示的设置内存对齐方式(通过StructLayout.Pack属性决定), C#默认是以4个字节(byte)为单位,会出现“多分配”内存的情况。 例如:

Class Example{   public byte b1;   public char c2;   public int i3;}

默认情况下(StructLayout.Pack = 4),Framework编译器会为example对象分配8个字节(字段c2后面会补齐2个byte )。每个成员的索引和大小结果为:

     Size: 8

     b1 Offset: 0, lenght =1, 

     c2 Offset: 1, length = 1,

     i3 offset: 4, length = 4

 

C++ 编译器的分配方式则为:

  Size: 6

     b1 Offset: 0, lenght =1, 

     c2 Offset: 1, length = 1,

     i3 offset: 2, length = 4

 

由于内存分配的大小不一致,导致在传递对象marshal的时候回出现问题!!

 

3. 解决方案。

3.1 通过设置StructLayout.Pack的值来达到内存大小分配一致。

例如在上面的例子中,设置StructLayout.Pack =2 或者 StructLayout.Pack =1. 但是这种方法可能会因为硬件约束导致性能或者其他问题。

 

3.2 通过预留字段来“补齐”内存分配。

这种做法在实际项目中使用较多,既保证了长度一致,也为以后扩展提供了一种容错的可能。 如果采取这种方式,重新定义如下:

Class Example{   public byte b1;   public char c2;   public int i3;      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]   public byte[] reserved;}

至此,C#和C++分配的内存大小同为8,问题解决  :)  

 

 

 

转载于:https://www.cnblogs.com/atuotuo/p/5019630.html

你可能感兴趣的文章
python习题:unittest参数化-数据从文件或excel中读取
查看>>
Android控件之GridView探究
查看>>
在工程中要加入新的错误弹出方法
查看>>
PS 滤镜— — sparkle 效果
查看>>
snmpwalk命令常用方法总结
查看>>
网站产品设计
查看>>
C++按格式接收输入字符(京东,滴滴,360笔试必用)
查看>>
代理ARP
查看>>
go 学习笔记(4) ---项目结构
查看>>
java中静态代码块的用法 static用法详解
查看>>
Java线程面试题
查看>>
Paper Reading: Relation Networks for Object Detection
查看>>
Java IO流学习总结
查看>>
day22 01 初识面向对象----简单的人狗大战小游戏
查看>>
递归函数,二分运算,正则表达式
查看>>
Flutter之内置动画(转)
查看>>
MySql优化相关概念的理解笔记
查看>>
数据库解决方案
查看>>
DataContract和DataMember的作用
查看>>
js如何获取response header信息
查看>>