如何转换Python';字节';反对ctypes';指针(c#u字节)和#x27;
我想用以下签名为C函数编写ctypes包装器:如何转换Python';字节';反对ctypes';指针(c#u字节)和#x27;,python,python-3.x,ctypes,Python,Python 3.x,Ctypes,我想用以下签名为C函数编写ctypes包装器: int utp_process_udp(utp_context *ctx, const byte *buf, size_t len, const struct sockaddr *to, socklen_t tolen); 为了进行一些类型检查,我在Python包装中添加了以下内容: libutp.utp_process_udp.argtypes = [POINTER(UtpContext), POINTER(c_byte), c_size_t,
int utp_process_udp(utp_context *ctx, const byte *buf, size_t len, const struct sockaddr *to, socklen_t tolen);
为了进行一些类型检查,我在Python包装中添加了以下内容:
libutp.utp_process_udp.argtypes = [POINTER(UtpContext), POINTER(c_byte), c_size_t, POINTER(sockaddr_in), c_int]
但是当我将bytes
对象作为buf
参数传递时,我得到以下错误:
Traceback (most recent call last):
File "ucat.py", line 269, in <module>
main()
File "ucat.py", line 251, in main
network_loop()
File "ucat.py", line 138, in network_loop
utp.utp_process_udp(ctx, data, addr)
File "/home/mostafa/source/pyutp/utp.py", line 159, in utp_process_udp
POINTER(c_byte)(data), c_size_t(len(data)),
TypeError: expected c_byte instead of bytes
回溯(最近一次呼叫最后一次):
文件“ucat.py”,第269行,在
main()
文件“ucat.py”,第251行,主
网络环路()
文件“ucat.py”,第138行,在网络循环中
utp.utp_进程_udp(ctx、数据、地址)
文件“/home/mostafa/source/pyutp/utp.py”,第159行,在utp\u进程中
指针(c_字节)(数据),c_大小(len(数据)),
TypeError:应为c_字节,而不是字节
如果我没有设置
argtypes
,我可以成功调用该函数,因此显然bytes
对象可以传递给该函数。我应该做些什么让ctypes知道我在做什么?也许是什么演员?(我试过使用ctypes.cast
函数,但没有成功。)我只是用指针(c_char)
代替指针(c_byte)
,问题就解决了。你可以用c_char p
代替。请注意,在这种情况下,可以传递一个不可变的bytes
对象,因为参数类型被限定为const byte
指针。@eryksun文档明确表示c\u char\u p
用于以NULL结尾的字符串,而这显然不是其中之一。因此,类型很重要,因为getfunc会尝试自动创建字符串,寻找可能不存在的空终止符。这可能是错误的,所以是的,这是结果类型的一个重要区别。作为参数类型,它一点也不重要。C函数看到的只是一个指向字符串第一个字节的指针。顺便说一句,CPythonbytes
和str
类型被实现为以null结尾的字符串c_char_p.from_param
传递对象的内部指针。这就是为什么对于标记为const
的参数,必须小心地只传递字节
和str
。否则,您可能会违反CPython的期望,即不可变对象可以被托管。另外请注意,指针
使用一个类型缓存,指针(c\char)
已经定义,并且特殊情况下使用from\u param
converter方法fromc\u p
,即行指针(c\char).from_param=c_char_p.\u reset_cache
功能中的from_param
。