char数组到未签名的char python

char array to unsigned char python

本文关键字:char python 数组      更新时间:2023-10-16

我正试图将这段c代码翻译成python,但我在char*ushort*的转换方面遇到了问题:

void sendAsciiCommand(string command) {
    unsigned int nchars = command.length() + 1; // Char count of command string
    unsigned int nshorts = ceil(nchars / 2);    // Number of shorts to store the string
    std::vector<unsigned short> regs(nshorts);  // Vector of short registers
    // Transform char array to short array with endianness conversion
    unsigned short *ascii_short_ptr = (unsigned short *)(command.c_str());
    for (unsigned int i = 0; i < nshorts; i++)
         regs[i] = htons(ascii_short_ptr[i]);          
    return std::string((char *)regs.data());
}

只要我在Python 2.7:中尝试过这段代码

from math import ceil
from array import array

command = "hello"
nchars = len(command) + 1
nshorts = ceil(nchars/2)
regs = array("H", command)

但它给了我一个错误:

ValueError:字符串长度不是项目大小的倍数

有什么帮助吗?

异常文本:

ValueError: string length not a multiple of item size

意思是说,也就是说,试图创建数组的字符串的长度必须是项大小的倍数。在这种情况下,项目大小是unsigned short的大小,即2个字节。因此,字符串的长度必须是2的倍数。hello的长度为5,而不是2的倍数,因此您不能从中创建一个2字节整数的数组。如果字符串为6字节长,则它会起作用,例如hello!

>>> array("H", 'hello!')
array('H', [25960, 27756, 8559])

您可能仍然需要转换为网络字节顺序。array在您的机器上使用本机字节顺序,因此如果您的本机字节序是小端序,则需要将其转换为大端序(网络字节顺序)。使用sys.byteorder进行检查,如果需要,使用array.byteswap()交换字节顺序:

import sys
from array import array
s = 'hello!'
regs = array('H', s)
print(regs)
# array('H', [25960, 27756, 8559])
if sys.byteorder != 'big':
    regs.byteswap()
print(regs)
# array('H', [26725, 27756, 28449])

然而,如果需要,使用struct.unpack()将直接转换为网络字节顺序更容易:

import struct
s = 'hello!'
n = len(s)/struct.calcsize('H')
regs = struct.unpack('!{}H'.format(n), s)
print(regs)
#(26725, 27756, 28449)

如果你真的需要array:

regs = array('H', struct.unpack('!{}H'.format(n), s))

同样值得指出的是,您的C++代码包含一个错误。如果字符串长度为奇数,则会在字符串末尾读取一个额外的字节,并将其包含在转换后的数据中。这个额外的字节将是,因为C字符串应该以null结尾,但最后一个unsigned short应该被忽略,或者你应该检查字符串的长度是unsigned short的倍数,就像Python一样。