gpt4 book ai didi

python - 有没有等同于 Memcpy 的 Python

转载 作者:太空狗 更新时间:2023-10-30 01:49:12 24 4
gpt4 key购买 nike

我正在尝试移植一些 C 代码,但由于使用 memcpy 我尝试使用 ctypes(没有用),我真的卡住了。我希望找到一种使用 memcpy 等效函数的 python 方法

任何想法

这是我尝试移植的 C 代码示例

i = l + 5;
t = htons(atoi(port));
memcpy((buf+i), &t, 2);

最佳答案

您几乎可以肯定不需要调用 htons 然后将 2 个字节复制到缓冲区中——请参阅 Keith 的回答以了解原因。

但是,如果您确实需要这样做(也许您正在制作 IP 数据包以与捕获的有线数据包进行比较作为测试或其他什么?),您可以。

首先,如果您使用的是 bytearray(或任何其他符合可写缓冲区协议(protocol)的东西),您只需使用普通的 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)

我刚刚定义了一个按网络顺序排列的结构,四个字节后跟一个短字符,并将我的数据打包到其中。

最后要提的一件事:如果你真的想使用 C 风格代码处理 C 风格变量,ctypes模块是另一种选择。它是专门为与 C 代码交互而设计的,所以通常它是相当低级的(并且是标准库中唯一允许您对代码进行段错误的模块),但它可以让您构建一些看起来更漂亮的中级东西像 C:

class ADDRPORT(ctypes.BigEndianStructure):
_fields_ = [("addr", ctypes.c_char*4),
("port", ctypes.c_short)]

addrport = ADDRPORT(addrbytes, portshort)

由于您的 C 代码逐渐填充缓冲区,而不是设置 struct 的元素,这可能不是您想要的。但值得注意的是,它可能会在某个时候成为您想要的。

关于python - 有没有等同于 Memcpy 的 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13689628/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com