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,问题解决  :)  

最新文章

  1. rsync 通过 ssh 上传文件
  2. jboss的时区问题
  3. OC类方法和实例方法中的self区别
  4. BZOJ1722 [Usaco2006 Mar] Milk Team Select 产奶比赛
  5. hdu2717 Catch That Cow
  6. STL模板_map
  7. php+mysql 内联接 和 子查询
  8. Mac上关于shell使用Python3和C++11声明
  9. Linq学习系列-----1.2 一个简单方法的改进思考及不同的执行形式
  10. Python3实现ICMP远控后门(中)之“嗅探”黑科技
  11. 使用FaceNet 图像相识度对比
  12. js实现复选框的全选、全不选和反选
  13. 三十九、Linux 线程——线程的同步和互斥
  14. Confluence 6 嵌入的 H2 数据库
  15. 运行yarn的时候提示 node不是内部或外部命令
  16. BugPhobia终章篇章:学霸在线系统Beta阶段展示
  17. Calendar获取当前年份、月份、日期
  18. 【Android自动化】编写一个log模块,输出至控制台,供程序运行查看
  19. Linux - 用户操作
  20. 使用Axure RP原型设计实践06,登录验证

热门文章

  1. 1089 最长回文子串 V2(Manacher算法)
  2. 谁让APP工程师产生了泡沫?
  3. 招聘前端、Java后端开发、测试、Mysql DBA
  4. 在c#中使用指针
  5. 特征检测(feature detection)的一些资料
  6. c# DES加密解密
  7. Css 知识点(不要删)
  8. java 跨平台 数据类型 修饰符 程序结构
  9. 关于分页接口设计(下拉刷新上拉加载原理,解决page count请求重复数据的问题)
  10. Java编程思想重点笔记(Java开发必看)