我正在尝试移植一些C代码,但由于使用了memcpy函数,我真的卡住了。我尝试使用ctypes(但失败了)。我希望能找到一种Python方式来使用memcpy的等效函数。
有什么想法吗?
这里是我正在尝试移植的C代码示例:
i = l + 5;
t = htons(atoi(port));
memcpy((buf+i), &t, 2);
htons
,然后将2个字节复制到缓冲区中 - 请参阅Keith的答案以了解原因。bytearray
(或任何符合可写缓冲区协议的内容),则只需使用普通的list
样式切片赋值即可。# like C's memcpy(buf+i, foo, 2)
buf[i:i+2] = foo
foo
,而是有一个短整数。在C中,你可以通过使用&
运算符获取其地址将其转换为两个字节的指针,但Python不能这样做。幸运的是,有一个标准库模块叫做struct
专门用于这种情况:t = socket.htons(int(port))
buf[i:i+2] = struct.pack('h', t)
或者,因为struct
可以为您处理字节序:
t = int(port)
buf[i:i+2] = struct.pack('!h', t)
然而,通常情况下您甚至不需要缓冲区复制; 您可以在struct
内一次性定义整个结构。例如,如果您要将IP地址和端口打包到6字节数组中,则可以执行此操作:
buf = bytearray(6)
i = 0
addrbytes = [int(part) for part in addr.split('.')]
buf[i:i+4] = struct.pack('4B', addrbytes[0], addrbytes[1], addrbytes[2], addrbytes[3])
i += 4
portshort = int(port)
buf[i:i+2] = struct.pack('!h', portshort)
addrbytes = [int(part) for part in addr.split('.')]
portshort = int(port)
buf = struct.pack('!4Bh', addrbytes[0], addrbytes[1], addrbytes[2], addrbytes[3], portshort)
class ADDRPORT(ctypes.BigEndianStructure):
_fields_ = [("addr", ctypes.c_char*4),
("port", ctypes.c_short)]
addrport = ADDRPORT(addrbytes, portshort)
由于您的C代码是逐步填充缓冲区,而不是设置struct
的元素,因此这可能不是您想要的。但是,值得注意的是,因为在某些时候这可能是您想要的。
看起来你正在尝试从用户输入或字符串中获取端口号。
在Python中:
port = int(port)
socket = socket.socket(("127.0.0.1", port))
Python会为您完成htons
转换。在TCP的情况下,您只需要提供一个由字符串和整数组成的元组作为套接字的地址。
socket
库可以为您完成许多这方面的工作,因此在Python代码中不必担心使用htons()
等函数。因此,如果没有看到更多C代码,很难说清楚。 - Greg Hewgill