char数组到unsigned char python

时间:2016-07-20 09:55:24

标签: python c++

我试图将此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:字符串长度不是项目大小的倍数

任何帮助?

1 个答案:

答案 0 :(得分:0)

例外文字:

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使用机器上的本机字节顺序,因此如果您的本机字节顺序是小端,则需要将其转换为big endian(网络字节顺序)。如果需要,使用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 ++代码包含错误。如果字符串长度为奇数,则将在字符串末尾读取额外字节,这将包含在转换后的数据中。该额外字节将为\0,因为C字符串应为空终止,但应忽略最后一个unsigned short,或者您应检查该字符串的长度是{{1}的倍数就像Python一样。