下面我有一些代码应该将C(Arduino)8位字节数组转换为16位int数组,但它似乎只能部分工作。我不确定我做错了什么。
字节数组采用小端字节顺序。如何将其转换为int(每个enty两个字节)数组?
用外行人的话说,我想合并每两个字节。
目前正在输出输入BYTE ARRAY:{0x10, 0x00, 0x00, 0x00, 0x30, 0x00}
。输出INT ARRAY是:{1,0,0}
。输出应该是INT ARRAY:{1,0,3}
。
以下代码是我目前的代码:
我根据a solution in Stack Overflow question Convert bytes in a C array as longs编写了这个函数。
我也有这个基于相同代码的解决方案,它适用于字节数组到长(32位)数组http://pastebin.com/TQzyTU2j
。
/**
* Convert the retrieved bytes into a set of 16 bit ints
**/
int * byteA2IntA(byte * byte_slice, int sizeOfB, int * ret_array){
//Variable that stores the addressed int to be stored in SRAM
int currentInt;
int sizeOfI = sizeOfB / 2;
if(sizeOfB % 2 != 0) ++sizeOfI;
for(int i = 0; i < sizeOfB; i+=2){
currentInt = 0;
if(byte_slice[i]=='\0') {
break;
}
if(i + 1 < sizeOfB)
currentInt = (currentInt << 8) + byte_slice[i+1];
currentInt = (currentInt << 8) + byte_slice[i+0];
*ret_array = currentInt;
ret_array++;
}
//Pointer to the return array in the parent scope.
return ret_array;
}
答案 0 :(得分:2)
这行代码的含义是什么?
if(i + 1 < sizeOfB) currentInt = (currentInt << 8) + byte_slice[i+1];
此处currentInt
始终为0
和0 << 8 = 0
。
另外,对于每对bytes
(我从现在开始称呼他们为uint8_t
),你所做的就是打包int
(让我称之为uint16_t
从现在开始)通过执行以下操作:
uint8_t
uint8_t
这真的是你想要的吗?
假设您有byte_slice[] = {1, 2}
,则打包一个16位整数,其值为513(2<<8 + 1
)!
此外,您不需要将指针返回到uint16_t
数组,因为调用者已将其提供给函数。
如果你使用函数的返回,正如Joachim所说,你得到一个从uint16_t
数组的位置开始的指针,它不是位置[0]
。
答案 1 :(得分:2)
Vincenzo有一点(或两点),你需要明确你要做的事情;
将两个字节合并为一个16位int,一个字节为MSB,一个字节为LSB
int16 result = (byteMSB << 8) | byteLSB;
将字节数组转换为16位
for(i = 0; i < num_of_bytes; i++)
{
myint16array[i] = mybytearray[i];
}
将数据数据复制到另一个数据
memcpy(dest, src, num_bytes);
那将(可能是平台/编译器依赖)与我的第一个例子具有相同的效果。
另外,谨防使用整数表示签名值,使用uints,更安全,可能更快。
答案 2 :(得分:1)
问题很可能是您增加ret_array
然后返回它。当您返回它时,它将指向目标数组之外的一个位置。
将指针保存在函数的开头,然后使用该指针。
答案 3 :(得分:1)
考虑使用结构。不过,这有点像黑客。
我的头顶看起来就像这样。
struct customINT16 {
byte ByteHigh;
byte ByteLow;
}
所以在你的情况下你会写:
struct customINT16 myINT16;
myINT16.ByteHigh = BYTEARRAY[0];
myINT16.ByteLow = BYTEARRAY[1];
你必须通过一个指针来投射它,但是:
intpointer = (int*)(&myINT16);
INTARRAY[0] = *intpointer;