简体   繁体   English

是否有一个与Memcpy相当的Python

[英]is there a Python Equivalent to Memcpy

I am trying to port some C Code but I am really stuck cause of the use of memcpy I tried with ctypes (did not work). 我试图移植一些C代码,但我真的卡住使用memcpy我尝试用ctypes(没有工作)。 I am hoping to find a python way of using an equivalent function of memcpy 我希望找到一种使用memcpy等效函数的python方法

Any ideas 有任何想法吗

Here is an example of the C Code I am trying to port 这是我尝试移植的C代码的示例

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

You almost certainly don't need to call htons and then copy the 2 bytes into a buffer—see Keith's answer for why. 您几乎肯定不需要调用htons然后将2个字节复制到缓冲区中 - 请参阅Keith的答案。

However, if you do need to do this (maybe you're crafting IP packets to compare to captured wire packets as a test or something?), you can. 但是,如果你确实需要这样做(也许你正在制作IP数据包来比较捕获的线程数据包作为测试或什么?),你可以。

First, if you're using a bytearray (or anything else that meets the writable buffer protocol), you just use normal list -style slice assignment: 首先,如果您正在使用bytearray (或任何其他符合可写缓冲区协议的内容),您只需使用普通的list -style切片赋值:

# like C's memcpy(buf+i, foo, 2)
buf[i:i+2] = foo

You don't have that two-byte string foo ; 你没有那个双字节的字符串foo ; you have a short integer. 你有一个短整数。 In C, you can turn that into a pointer to two bytes just by using the & operator to get its address, but Python can't do that. 在C中,只需使用&运算符获取其地址,就可以将其转换为指向两个字节的指针,但Python无法做到这一点。 Fortunately, there's a standard library module called struct designed for exactly this kind of thing: 幸运的是,有一个名为struct的标准库模块,专门用于此类事情:

t = socket.htons(int(port))
buf[i:i+2] = struct.pack('h', t)

Or, because struct can handle endianness for you: 或者,因为struct可以为您处理字节序:

t = int(port)
buf[i:i+2] = struct.pack('!h', t)

However, often you don't even need the buffer copying; 但是,通常你甚至不需要缓冲区复制; you can define the entire structure all at once inside struct . 你可以在struct中一次定义整个结构。 For example, if you're trying to pack an IP address and port into a 6-byte array, you could do this: 例如,如果您尝试将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)

But this is much simpler: 但这更简单:

addrbytes = [int(part) for part in addr.split('.')]
portshort = int(port)
buf = struct.pack('!4Bh', addrbytes[0], addrbytes[1], addrbytes[2], addrbytes[3], portshort)

I've just defined a structure that's in network order, with four bytes followed by a short, and packed my data into it. 我刚刚定义了一个网络顺序的结构,有四个字节后跟一个short,并将我的数据打包到其中。

One last thing to mention: If you really want to deal with C-style variables using C-style code, the ctypes module is another option. 最后要提一句:如果你真的想使用C风格的代码处理C风格的变量,那么ctypes模块是另一种选择。 It's made specifically for interacting with C code, so in general it's pretty low-level (and the only module in the standard library that lets you segfault your code), but it let you build some nice mid-level stuff that looks a little more like C: 它专门用于与C代码进行交互,因此通常它是相当低级的(并且标准库中唯一允许您对代码进行分段的模块),但它可以让您构建一些看起来更多的中级内容喜欢C:

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

addrport = ADDRPORT(addrbytes, portshort)

Since your C code is progressively filling up a buffer, rather than setting elements of a struct , this probably isn't what you want. 由于您的C代码逐渐填充缓冲区,而不是设置struct元素,这可能不是您想要的。 But it's worth being aware of, because it probably will be what you want at some point. 但值得注意的是,因为它可能会在某些时候成为你想要的。

It looks like you are trying to get a port number from user input or a string. 看起来您正在尝试从用户输入或字符串中获取端口号。

In Python: 在Python中:

port = int(port)

Then you can pass that directly to a socket instantiation: 然后你可以直接将它传递给套接字实例化:

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

Python does the htons translation for you. Python为你做了htons翻译。 You only need to supply an address to a socket (in the case of TCP) as a tuple of a string and integer. 您只需要为套接字(在TCP的情况下)提供一个地址作为字符串和整数的元组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM