有一个Python相当于的memcpy [英] is there a Python Equivalent to Memcpy

查看:4802
本文介绍了有一个Python相当于的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆