【问题标题】:is there a Python Equivalent to Memcpy是否有与 Memcpy 等效的 Python
【发布时间】:2012-11-21 07:05:11
【问题描述】:

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

任何想法

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

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

【问题讨论】:

  • 你真正想要达到什么目的?显示你的 python 代码。
  • 这似乎是与套接字相关的代码。 Python socket 库为你做了很多这样的事情,所以你不必担心在 Python 代码中使用 htons() 等。因此,如果没有看到更多的 C 代码,很难说。
  • 非常、非常少您想要直接进行逐行转码。这是低效的,并且无法利用新语言的优势。
  • 我会问@marcin 是什么——你想要做什么......例如,最终目标是什么?

标签: python c memcpy


【解决方案1】:

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

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

首先,如果您使用的是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)

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

最后要提一提:如果您真的想使用 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 的元素,这可能不是您想要的。但值得注意的是,它可能会在某个时候成为您想要的。

【讨论】:

    【解决方案2】:

    您似乎正试图从用户输入或字符串中获取端口号。

    在 Python 中:

    port = int(port)
    

    然后你可以将它直接传递给套接字实例化:

    socket = socket.socket(("127.0.0.1", port))
    

    Python 为您进行htons 翻译。您只需将地址作为字符串和整数的元组提供给套接字(在 TCP 的情况下)。

    【讨论】:

    • 除非他试图,例如,制作原始 IP 数据包而不是仅仅创建一个套接字,否则这是正确的答案。
    猜你喜欢
    • 2012-05-14
    • 2013-02-04
    • 2011-03-20
    • 2012-08-26
    • 1970-01-01
    • 2013-06-07
    • 2011-07-14
    • 2010-12-19
    • 2011-02-18
    相关资源
    最近更新 更多