请进来解释一下>>>>>>看代码说话

问题描述

C++中定义结构体:#if(defined(AIX)&&defined(__xlC__))#pragmaoptionsalign=packed#else#pragmapack(1)#endiftypedefstruct{charszServerName[33];intnProtocal;charszAddress[33];intnPort;charszSendQName[33];charszReceiveQName[33];charszReserved[33];}tagConnectOption;sizeof(tagConnectOption)=173

C#中定义publicstructtagConnectOption{[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;publicInt16nProtocal;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szAddress;publicInt16nPort;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szSendQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReceiveQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReserved;publictagPConnectOption(intserNameMax,intdesMax){szServerName=newbyte[33];nProtocal=0;szAddress=newbyte[33];nPort=0;szSendQName=newbyte[33];szReceiveQName=newbyte[33];szReserved=newbyte[33];}}Marshal.SizeOf(tagPConnectOption)=172

进一步publicstructtagConnectOption{[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;//publicInt16nProtocal;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szAddress;publicInt16nPort;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szSendQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReceiveQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReserved;publictagPConnectOption(intserNameMax,intdesMax){szServerName=newbyte[33];//nProtocal=0;szAddress=newbyte[33];nPort=0;szSendQName=newbyte[33];szReceiveQName=newbyte[33];szReserved=newbyte[33];}}Marshal.SizeOf(tagPConnectOption)=168

publicstructtagConnectOption{[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;//publicInt16nProtocal;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szAddress;//publicInt16nPort;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szSendQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReceiveQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReserved;publictagPConnectOption(intserNameMax,intdesMax){szServerName=newbyte[33];//nProtocal=0;szAddress=newbyte[33];//nPort=0;szSendQName=newbyte[33];szReceiveQName=newbyte[33];szReserved=newbyte[33];}}Marshal.SizeOf(tagPConnectOption)=165

在C++中的字长很容易理解,33*5+4*2=173,为什么在C#中少了一个字节变成172了呢?进一步当C#中没有定义Int16时,为33*5=165容易理解;定义一个Int16时为168在原来基础上增加了3字节???费解啊费解啊

解决方案

解决方案二:
lz精神让我pf.
解决方案三:
具体你可以看下struct在各语言的说明
解决方案四:
和内存对齐有关系,第一段C++程序中,#pragmapack(1)指定了对齐时封装大小是1,你可以试试设成8应该就和C#的结果一样了。(印象中封转大小默认是8)在C#中,如果没有指定struct的内存对齐方式,默认为LayoutKind.Sequential,封装大小为8参考一下这篇文章:,里面讲解了对齐规则。解释一下为何下面这段占用168[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;//publicInt16nProtocal;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szAddress;publicInt16nPort;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szSendQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReceiveQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReserved;

首先,[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;相当于写了33个byte在这里,对齐是按照每个byte来对齐的,不是按照整个数组对齐,byte长度是1,1<8,按照1对齐,这就能导致szAddress从第33字节开始对齐,而不是从第40字节而Int16占用两个字节,按照2来对齐,所以整个struct在内存中的布局是[0szServerName32][33szAddress65][66nPort67][68szSendQName100][101szReceiveQName133][134szReserved166][167]最后的167是补了一个空字节,因为要将整个结构体大小控制为8的倍数。其他几个类似,只要弄明白了布局规则,就OK了。
解决方案五:
最后的167是补了一个空字节,因为要将整个结构体大小控制为8的倍数。其他几个类似,只要弄明白了布局规则,就OK了。-------------------------------------------------------------这句话说错了,应该是控制为2的倍数,因为是“结构的整体对齐规则:在数据成员完成各自对齐之后,结构本身也要进行对齐,对齐将按照pack指定的数值和结构最大数据成员长度中,比较小的那个进行”也就是Int16的长度2
解决方案六:
谢谢ivorstar的耐心回答!照此解释publicstructtagConnectOption{[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szServerName;publicInt16nProtocal;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szAddress;publicInt16nPort;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szSendQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReceiveQName;[MarshalAs(UnmanagedType.ByValArray,SizeConst=33)]publicbyte[]szReserved;publictagPConnectOption(intserNameMax,intdesMax){szServerName=newbyte[33];nProtocal=0;szAddress=newbyte[33];nPort=0;szSendQName=newbyte[33];szReceiveQName=newbyte[33];szReserved=newbyte[33];}}Marshal.SizeOf(tagPConnectOption)=172

[0szServerName32][33nProtocal34][35szAddress67][68nPort69][70szSendQName102][103szReceiveQName135][136szReserved168][169]这个为什么不是170而是172呢?
解决方案七:
自己醒悟过来了,上面结构中应该是逐项对齐的,即布局为:1),数据成员各自对齐[0szServerName32][33nProtocal34][35][36szAddress68][69nPort70][71][72szSendQName104][105szReceiveQName137][138szReserved170]2),数据成员完成各自对齐,结构本身进行对齐[0szServerName32][33nProtocal34][35][36szAddress68][69nPort70][71][72szSendQName104][105szReceiveQName137][138szReserved170][171]对吗?有待高手肯定
解决方案八:

解决方案九:

解决方案十:

解决方案十一:
再顶一下回家了,明天来看
解决方案十二:
引用6楼Kinpring的回复:

自己醒悟过来了,上面结构中应该是逐项对齐的,即布局为:1),数据成员各自对齐[0szServerName32][33nProtocal34][35][36szAddress68][69nPort70][71][72szSendQName104][105szReceiveQName137][138szReserved170]

1),[0szServerName32][33][34nProtocal35][36szAddress68][69][70nPort71][72szSendQName104][105szReceiveQName137][138szReserved170]……可以再参照参照上面链接里的例子,在考虑自身布局的时候,nProtocal总是努力把自己放在一个好找的位置——起始位置=Min(自身长度,封装长度)的倍数
解决方案十三:
该回复于2008-04-04 11:28:37被版主删除
解决方案十四:
明白了谢谢ivorstar!

时间: 2024-12-06 22:05:04

请进来解释一下>>>>>>看代码说话的相关文章

离散数学-请各位解释一下真值函数的概念。

问题描述 请各位解释一下真值函数的概念. 老师课堂上讲了,也上网查了,但还是不懂,所以来问大家.希望能具体点. 解决方案 因为每个参数都是bool值,每个函数有确定的值. 所以我们可以列出全部可能2^(参数个数),以及对应的返回值,这就是真值表.比如all这个函数,我们可以列出: b1 b2 b3 result 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 0 1 1 0 0 1 1 1 1 解决方案二: 它采用来自 {T,F} (就是真实和虚假)的

android-研究过Android /proc/目录的请进来~~

问题描述 研究过Android /proc/目录的请进来~~ 如果有研究过/proc/目录下面的文件的都知道,/proc/目录下包含着系统运行的各种信息,包括CPU,内存等等,还记录着从开机开始每个进程的信息.并且这些信息更新得很快,很频繁. 我的问题是,有人知道android系统是在什么时候写入这些信息吗?在哪里写入的?多久写入一次? 有知道的请回复下,我们一起讨论交流~ 解决方案 这个是内核虚拟出来的,内核会把这些硬件信息虚拟成一个个文件,给用户态程序访问,获取这些数据 解决方案二: 这个是

懂交叉编译或ld.so.conf或者或者zedboard或者动态库相关的请进来。。

问题描述 懂交叉编译或ld.so.conf或者或者zedboard或者动态库相关的请进来.. 小弟最近没事儿,又研究了一下交叉编译opencv的事情. 第一步:在电脑上交叉编译opencv,make,make install之后,我把相关的include/和/lib和/share分别拷贝到zedboard板上的/usr/local/include ,/usr/local/lib/ ,/usr/local/share.在板子上运行的是linaro桌面系统. 第二步:在电脑上我用cmake指定交叉编

服务器-【菜鸟求助】请进来帮帮忙weblogic11g的

问题描述 [菜鸟求助]请进来帮帮忙weblogic11g的 具体情况: 我的本地环境是weblogic8和JDK1.4,项目启动,运行都没问题,现在是把这个项目放到一个服务器上,服务器的环境是weblogic11g,JDK1.6,(至于为啥会这样,别在意这些细节了)启动运行也没问题,但是当跳转到,调用FileY,这个类的页面时候,就会报下面的错 [ServletContext@3843485[app:sdywxt module:sdywxt path: spec-version:null]] S

quartus verilog-verilog大神请进来看看 小弟跪谢

问题描述 verilog大神请进来看看 小弟跪谢 我用quartusii仿真出现的情况 用Cyclone III仿真出现的严重警告但是 但是用其他器件仿真就不会出现严重警告 请问一下怎么解决 还有为什么用Cyclone III仿真就会出现严重警告 Critical Warning: Synopsys Design Constraints File file not found: 'test.sdc'. A Synopsys Design Constraints File is required

js-asp.net 后台控制前台<a>标签的问题 请进来看看

问题描述 asp.net 后台控制前台<a>标签的问题 请进来看看 asp.net 后台控制前台标签的问题 请看图片 我在后台写好了 if(uname=="admin") { daor.visble=false; } 标签是隐藏了 但是点击原来lable在的地方 还是可以触发 后来才发现是在标签标签里面了 怎么样把标签也隐藏起来或者不让它点击触发事件呢? 解决方案 a标签增加runat='server'属性,设置addreport.Visible=false,而不是设置la

c#-请帮忙解释下下列函数的作用。谢谢

问题描述 请帮忙解释下下列函数的作用.谢谢 输入的参数是鼠标的X,Y坐标,请问转换后是什么? private static int MAKEPARAM(int l, int h) { return ((l & 0xffff) | (h << 0x10)); } 解决方案 其实这代码就是把l的最低16位和h的最高16位放在一起. 解决方案二: private static int MAKEPARAM(int l, int h) { return h * 65536 + l % 65536

请帮忙解释NewLateBinding.LateGet()功能

问题描述 请帮忙解释NewLateBinding.LateGet(null,typeof(Math),"Round",objArray2,null,null,flagArray)是什么意思?怎么用C#代替它doubleddd=Convert.ToDouble(NewLateBinding.LateGet(null,typeof(Math),"Round",objArray2,null,null,flagArray)); 解决方案 解决方案二:帮你顶起,让大家帮帮忙.

请帮忙解释一下这条语句

问题描述 请帮忙解释一下这条语句 Authentication auth = RequestContextSecurity.getAuthentication(); 解决方案 参考:http://www.mossle.com/docs/springsecurity3/html/technical-overview.html