2024-10-06 16:23:10 发布
网友
我试图移植一些C代码,但我真的被困在memcpy的使用上了,我尝试了ctypes(没有工作)。我希望找到一种python方法来使用memcpy的等效函数
有什么想法吗
下面是我要移植的C代码的一个例子
i = l + 5; t = htons(atoi(port)); memcpy((buf+i), &t, 2);
看起来您正试图从用户输入或字符串中获取端口号。
在Python中:
port = int(port)
然后可以直接将其传递给套接字实例化:
socket = socket.socket(("127.0.0.1", port))
Python为您进行htons翻译。您只需要将地址作为字符串和整数的元组提供给套接字(在TCP的情况下)。
htons
您几乎肯定不需要调用htons,然后将2个字节复制到一个缓冲区中,请参阅Keith的答案。
但是,如果您需要这样做(也许您正在制作IP包以与捕获的有线包进行比较,作为测试或其他什么?),你可以。
首先,如果您使用的是bytearray(或任何满足可写缓冲区协议的内容),那么只需使用普通的list样式的片分配:
bytearray
list
# like C's memcpy(buf+i, foo, 2) buf[i:i+2] = foo
你没有两个字节的字符串foo;你有一个短整数。在C语言中,只需使用&操作符获取地址,就可以将其转换为指向两个字节的指针,但Python不能这样做。幸运的是,有一个名为^{}的标准库模块正是为这种情况而设计的:
foo
&
t = socket.htons(int(port)) buf[i:i+2] = struct.pack('h', t)
或者,因为struct可以为您处理endianness:
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中:
然后可以直接将其传递给套接字实例化:
Python为您进行
htons
翻译。您只需要将地址作为字符串和整数的元组提供给套接字(在TCP的情况下)。您几乎肯定不需要调用
htons
,然后将2个字节复制到一个缓冲区中,请参阅Keith的答案。但是,如果您需要这样做(也许您正在制作IP包以与捕获的有线包进行比较,作为测试或其他什么?),你可以。
首先,如果您使用的是
bytearray
(或任何满足可写缓冲区协议的内容),那么只需使用普通的list
样式的片分配:你没有两个字节的字符串} 的标准库模块正是为这种情况而设计的:
foo
;你有一个短整数。在C语言中,只需使用&
操作符获取地址,就可以将其转换为指向两个字节的指针,但Python不能这样做。幸运的是,有一个名为^{或者,因为
struct
可以为您处理endianness:然而,通常您甚至不需要缓冲区复制;您可以在
struct
中一次定义整个结构。例如,如果要将IP地址和端口打包到6字节数组中,可以执行以下操作:但这要简单得多:
我刚刚定义了一个按网络顺序排列的结构,四个字节后跟一个短字节,并将数据打包到其中。
最后要提的是:如果您真的想使用C样式代码处理C样式变量,ctypes模块是另一个选项。它是专门为与C代码交互而设计的,所以一般来说它是非常低级的(也是标准库中唯一一个允许您对代码进行分段的模块),但是它可以让您构建一些看起来更像C:
因为您的C代码正在逐渐地填充缓冲区,而不是设置
struct
的元素,所以这可能不是您想要的。但这是值得注意的,因为它可能会是你在某个时候想要的。相关问题 更多 >
编程相关推荐