有一个Python相当于的memcpy [英] is there a Python Equivalent to Memcpy
问题描述
我想端口一些C code,但我使用了memcpy我的ctypes尝试真正卡住原因(没有工作)。我希望能找到使用的memcpy的同等功能的蟒蛇方式
任何想法
下面是C code我试图端口的例子
其中i = 1 + 5;
T = htons(与atoi(端口));
的memcpy((BUF + I),amp; T公司,2);
您几乎肯定不需要调用 htons
,然后将2个字节复制到buffer-看到Keith的为什么的答案。
然而,如果你的做的需要这么做(也许你正在起草的IP数据包进行比较,以捕获的数据包线作为测试什么的?),就可以了。
首先,如果您使用的是字节组
(或其它任何符合读写缓存协议),您只需使用普通的列表
风格切片赋值:
#像C的的memcpy(BUF + I,富,2)
BUF [I:I + 2] = foo的
您没有两个字节的字符串富
;你有一个短整型。在C语言中,你可以把它转换成一个指向两个字节只使用&安培;
运算符来获得它的地址,但是Python不能这样做。幸运的是,被称为标准库模块 结构
设计正是这样的事情:
T = socket.htons(INT(口))
BUF [I:I + 2] = struct.pack('H',T)
或者,因为结构
可以处理字节序为您提供:
T = INT(口)
BUF [I:I + 2] = struct.pack('!H',T)
不过,很多时候你甚至不需要缓冲复制;你可以在结构
一下子定义整个结构。例如,如果你想装一个IP地址和端口成6个字节数组,你可以这样做:
BUF =字节组(6)
I = 0
addrbytes = [INT(部分),用于在addr.split部分('。')]
BUF [I:I + 4] = struct.pack(4B,addrbytes [0],addrbytes [1],addrbytes [2],addrbytes [3])
I + = 4
portshort = INT(口)
BUF [I:I + 2] = struct.pack('!H',portshort)
但是,这是更简单:
addrbytes = [INT(部分)在addr.split部分('。')]
portshort = INT(口)
BUF = struct.pack('!4BH',addrbytes [0],addrbytes [1],addrbytes [2],addrbytes [3],portshort)
我刚刚定义的结构这是在网络顺序,用四个字节后跟一个短,收拾好数据内容。
最后一件事说:如果你真的想使用C语言风格的code处理C风格的变量,那么的 ctypes的模块是另一种选择。它是专门制作供C code相互作用,所以一般是pretty低水平(在,让您段错误的code标准库中的唯一模块),但它让你建立一些不错中级的东西,看起来有点更像是C:
类ADDRPORT(ctypes.BigEndianStructure):
_fields_ = [(地址,ctypes.c_char * 4),
(端口,ctypes.c_short)addrport = ADDRPORT(addrbytes,portshort)
由于您的C code为逐步填补了一个缓冲区,而不是设置的元素结构
,这可能不是你想要的。但是你要在某些时候这是非常值得意识到的,因为它可能会。
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). I am hoping to find a python way of using an equivalent function of memcpy
Any ideas
Here is an example of the C Code I am trying to port
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.
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.
First, if you're using a bytearray
(or anything else that meets the writable buffer protocol), you just use normal list
-style slice assignment:
# like C's memcpy(buf+i, foo, 2)
buf[i:i+2] = foo
You don't have that two-byte string 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. Fortunately, there's a standard library module called struct
designed for exactly this kind of thing:
t = socket.htons(int(port))
buf[i:i+2] = struct.pack('h', t)
Or, because struct
can handle endianness for you:
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
. For example, if you're trying to pack an IP address and port into a 6-byte array, you could do this:
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.
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. 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:
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. But it's worth being aware of, because it probably will be what you want at some point.
这篇关于有一个Python相当于的memcpy的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!