代码报了个错:“byte array size is smaller than the size of the structur”,意思就是byte数组的大小小于结构体的大小,这个错报出来的原因是我代码中有个逻辑,需要将byte数组转换成结构体,但很显然,我没有转换成功,这是咋回事呢?
这个错报得我莫名其妙的,找了一个小时左右都没找到问题出在哪,但是最后发现问题的时候,我甚至有些无语。在说清楚问题到底出在哪之前,我们得先了解下代码的业务逻辑,然后您就知道为什么开始我觉得莫名其妙了!
代码的业务逻辑是这样的,我们的业务中有一个服务端和很多个客户端,客户端会定期给服务端发送消息,消息是以结构体的形式发送的,当然,在发送消息的时候,需要将结构体转换成byte数组。
为了确保发送消息的一致性,我特地封装了一个专门用来处理消息的函数库,这样就能确保每个客户端在发送和接收消息的时候不会出现任何差错。
但是,差错偏偏就出现了!在某个客户端上就出现了文章开头的那个错!
经过调试,我发现所有客户端发送的消息内容都是一样的,并没有任何区别。
结构体属于基本数据类型,因此在定义的时候,长度就已经确定了,我在服务端进行调试,发现结构体的长度为288,但是,服务端接收到的byte数组长度却只有280,如此一来,在将byte转换成结构体的时候,因为长度不一致,导致了转换失败。
前面说了,我专门封装了一个消息处理的库,服务端和客户端使用的是库里面同一个结构体,不可能会出现两边长度不一致的情况。
事出反常必有妖!
服务端是同一个服务端,因此问题只可能出现在客户端的代码上!因为我们的客户端有不同版本,每个版本有单独的代码,而代码只有略微差别。
我拿了不同版本的客户端代码进行调试,诡异的是,出问题的那个客户端在发送消息时,结构体的长度偏偏就是280,而其他客户端在发送消息时,结构体长度却是288!
一个小时都过去了,我硬是没找出问题所在,于是,我只能使用笨办法,那就是作对比,看看出问题的客户端代码和没出问题的客户端代码有什么不同。
这么一对比,就让我找到了差异点,原来,出问题的客户端代码在编译的时候勾选了“首选32位”,我一拍脑袋:“原来是这样!”
这个结构体的内容很简单,里面是由一个Int64字段+两个Int32字段+一个指针+一个指定了长度的字符串字段组成,其中,字符串的长度被指定为255。
公司代码是用C#编写的,在C#中,正常情况下,Int64所占字节数为8位,Int32所占字节数为4位,指针所占字节数为8位。
而指针类型在32位环境和64位环境里面所占用的字节是不一样的,在32位环境里占4个字节,而在64位环境里则占8个字节!
结语
因此,最终真相大白!于是我去除勾选“首选32位”,再次编译,发现结构体的长度变成了288!
说到这里,肯定有人关心为什么项目被勾选了“首选32位”,因为我一直没有将代码上传代码库,所以具体是怎么发生的,其实我也不知道,也许是IDE默认就给勾上了,但是因为一直没测到这,所以问题一直没被发现。
热门跟贴