C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题
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,问题解决 :)
C# 使用 StructLayoutAttribute 时 C# /C++ 内存空间分配与成员对齐问题的更多相关文章
- Spark内核| 调度策略| SparkShuffle| 内存管理| 内存空间分配| 核心组件
1. 调度策略 TaskScheduler会先把DAGScheduler给过来的TaskSet封装成TaskSetManager扔到任务队列里,然后再从任务队列里按照一定的规则把它们取出来在Sched ...
- C++使用继承时子对象的内存布局
C++使用继承时子对象的内存布局 // */ // ]]> C++使用继承时子对象的内存布局 Table of Contents 1 示例程序 2 对象的内存布局 1 示例程序 class ...
- eclipse启动时虚拟机初始内存配置
eclipse启动时虚拟机初始内存配置: -Xms256M -Xmx512M -XX:PermSize=256m -XX:MaxPermSize=512m
- C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆 这样说对吗
C++ 类T T t;构造时分配的内存在静态数据区 T t=new T()分配的内存在堆
- 使用C++做算法时,对内存的管理的办法
使用C++做算法时,对内存的管理的办法 最近老是在想C++的内存控制机制,查了一些资料所以有点想法,自己记录一下免得以后自己忘了. 1. 需求 在做线性代数的算法时,首要的就实现Matrix这个类.由 ...
- C#连接solr时提示 java内存异常 (jetty和tomcat哪个更High) java.lang.OutOfMemoryError
C#连接solr时提示 java内存异常 java.lang.OutOfMemoryError 时间:20180130 09:51:13.329,消息:异常消息<?xml version=& ...
- DenseNet算法详解——思路就是highway,DneseNet在训练时十分消耗内存
论文笔记:Densely Connected Convolutional Networks(DenseNet模型详解) 2017年09月28日 11:58:49 阅读数:1814 [ 转载自http: ...
- Linux OOM-killer 内存不足时kill高内存进程的策略
OOM_killer是Linux自我保护的方式,当内存不足时不至于出现太严重问题,有点壮士断腕的意味 在kernel 2.6,内存不足将唤醒oom_killer,挑出/proc/<pid> ...
- Linux OOM-killer(内存不足时kill高内存进程的策略)
OOM_killer是Linux自我保护的方式,当内存不足时不至于出现太严重问题,有点壮士断腕的意味 在kernel 2.6,内存不足将唤醒oom_killer,挑出/proc/<pid> ...
随机推荐
- ajax实现下拉菜单无刷新加载更多
$(function() { var page = 1; var discount = $('#discount'); var innerHeight = window.innerHeight; va ...
- C#.NET 大型通用信息化系统集成快速开发平台 4.1 版本 - .NET商业化成品成熟各种数据权限的需求对应例子代码
还是我上次提出的那个问题问题:假设一个订单表,1.角色A可以看自己的2.角色B可以看工作组的3.角色C可以看金额是1000元以下的(自定义条件是否可行?如果可以,请详细说明)4.角色D可以看整个部门的 ...
- javaScript 中的布尔运算符 && 和 ||
布尔运算符 && 和 ||的返回结果不一定是布尔值!由此来展开一定的研究及理解. 1.首先先介绍下常见的数据类型转化为bool后的值. (常用地方)在if表达式中,javascript ...
- ReactNative新手学习之路01-创建项目开始
新手学习之路01-创建项目开始 小菜鸟准备学习RN开发,决定写下自己的学习历程,方便其他也想要学习RN的人,后期会持续更新写下自己所有学习经历,一步步从菜鸟成长成业内高手.开发环境准备,本文默认环境已 ...
- JS获取回车事件(兼容各浏览器)
一.用到onkeydown获取事件动作, 二.用到键盘对应代码keyCode, 三. var event=arguments.callee.caller.arguments[0]||window.ev ...
- Java使用代理服务器
HTTP协议是基于TCP协议的,TCP协议在Java中的体现就是套接字.在了解HTTP协议的基础上,完全可以通过TCP来实现一套HTTP库,这个库可以发起网络请求和接受网络请求.只要能用URLConn ...
- 【knockout】ko绑定click事件传多个参数,
源:http://knockoutjs.com/documentation/event-binding.html <a href="javascript:;" class=& ...
- Angularjs+node+Mysql实现地图上特定点的定位以及附加信息展示
注:本博文为博主原创,转载请注明出处. 在上一篇博文中主要讲述了如何利用AngularJs+Node+MySql构建项目,并实现地图上的多点标注,今天在这篇文章中,我们将在上一个项目的基础上,实现特定 ...
- angular指令深度学习篇
angular指令深度学习-过滤器 limitTo ... <body ng-app="app" > <div ng-controller="myCtr ...
- 配置OWASP的ModSecurity规则
1.下载OWASP的ModSecurity规则 cd /etc/httpd git clone https://github.com/SpiderLabs/owasp-modsecurity-crs. ...