编程语言
首页 > 编程语言> > 将C移植到Python的惯用方式

将C移植到Python的惯用方式

作者:互联网

您将如何以Python方式移植以下C代码(尤其是Get2,Get3等的摆弄部分)

switch(mem[pos-1])
{
  ...
  case 0x10: pos+=Get2(&mem[pos+0x02])+0x04; break;
  case 0x11: pos+=Get3(&mem[pos+0x0F])+0x12; break;
  case 0x16: pos+=Get4(&mem[pos+0x00])+0x04; break;
  ...
  case 0x20: pos+=0x02; break;
}

...

//////////////////////////////////////////////////////////
// Conversion routines to fetch bytes in Big Endian order
//////////////////////////////////////////////////////////

unsigned int Get2(unsigned char *pointer)
{
  return (pointer[0] | (pointer[1]<<8));
}

unsigned int Get3(unsigned char *pointer)
{
  return (pointer[0] | (pointer[1]<<8) | (pointer[2]<<16));
}

unsigned int Get4(unsigned char *pointer)
{
  return (pointer[0] | (pointer[1]<<8) | (pointer[2]<<16) | (pointer[3]<<24));
}

到目前为止,这是我得到的:

    x = struct.unpack('B', mem[pos-1])[0]

    if x == 0x10:
        # pos += ???
        continue

    if x == 0x11:
        # pos += ???
        continue

    if x == 0x16:
        # pos += ???
        continue

    if x == 0x20: 
        pos += 0x02
        continue

解决方法:

如果您只是得到一个无符号字节,请执行

x = ord(mem[pos - 1])

在Python 2或

x = mem[pos - 1]

在Python 3上.

您需要字典,而不是select / case.

positions = {0x10: do_10, 0x11: do_12, 0x16: do_16}

其中do_10等是函数:

def do_10(pos):
    # This actually would need an endianness character
    return struct.unpack('H', mem[pos + 0x02])[0] + 0x04

您可以这样使用它:

pos += positions[mem[pos - 1]](pos)

如果要直接在字典中定义函数,则可以:

positions = {
    # This actually would need an endianness character
    0x10: (lambda pos: struct.unpack('H', mem[pos + 0x02])[0] + 0x04)
    # ...
    }

标签:bit-manipulation,c-3,python
来源: https://codeday.me/bug/20191102/1991065.html