无法弄清楚如何通过指针将结构传递给Python的C函数。 这就是我所拥有的(这是为nn_recvmsg项目实施nanomsg-python的更大努力的一部分:
...
msgHdr = NN_MSGHDR(iovecList)
pointer_type = ctypes.POINTER(NN_MSGHDR)
pp = pointer_type.from_address(ctypes.addressof(msgHdr))
print("argument type: "+str(pp))
print("function arguments: "+str(_nn_recvmsg.argtypes))
rtn = _nn_recvmsg(socket, pp, 0)
...
这给了我:
argument type: <_nanomsg_ctypes.LP_NN_MSGHDR object at 0x10b6d8d40>
function arguments: (<class 'ctypes.c_int'>, <class '_nanomsg_ctypes.LP_NN_MSGHDR'>, <class 'ctypes.c_int'>)
Traceback (most recent call last):
File "./test.py", line 11, in <module>
nnc.nn_recvmsg(s, [4, frameSize])
File "/Users/peetonn/Documents/Work/ptn-nanomsg-python/_nanomsg_ctypes/__init__.py", line 311, in nn_recvmsg
rtn = _nn_recvmsg(socket, pp, 0)
ctypes.ArgumentError: argument 1: <type 'exceptions.TypeError'>: wrong type
从输出中,我看到参数类型与函数预期的相同。但是,它仍然失败。
以下是我正在实现的功能的结构定义和完整代码:
class NN_IOVEC(ctypes.Structure):
_fields_ = [("iov_base", ctypes.c_void_p),
("iov_len", ctypes.c_size_t)]
class NN_MSGHDR(ctypes.Structure):
_fields_ = [("msg_iov", ctypes.POINTER(NN_IOVEC)), # ctypes.c_void_p),
("msg_iovlen", ctypes.c_int),
("msg_control", ctypes.c_void_p),
("msg_controllen", ctypes.c_size_t)]
def __init__(self, iovecList):
elems = (NN_IOVEC * len(iovecList))()
self.msg_iovlen = len(iovecList)
self.msg_iov = ctypes.cast(elems, ctypes.POINTER(NN_IOVEC))
for i in range(0, len(iovecList)):
self.msg_iov[i].iov_base = iovecList[i].iov_base
self.msg_iov[i].iov_len = iovecList[i].iov_len
self.msg_controllen = 0
self.msg_control = 0
def nn_recvmsg(socket, sizes = None):
"receive message/messages"
if sizes:
iovecList = []
for sz in sizes:
iovec = NN_IOVEC()
iovec.iov_len = sz
buf = (ctypes.c_char * sz)()
iovec.iov_base = ctypes.cast(buf, ctypes.c_void_p)
iovecList.append(iovec)
msgHdr = NN_MSGHDR(iovecList)
pointer_type = ctypes.POINTER(NN_MSGHDR)
pp = pointer_type.from_address(ctypes.addressof(msgHdr))
print("argument type: "+str(pp))
print("function arguments: "+str(_nn_recvmsg.argtypes))
rtn = _nn_recvmsg(socket, ctypes.byref(pp), 0)
print("here's the result: "+str(rtn))
if rtn < 0 :
print(nn_strerror(nn_errno()))
else:
pass # tbd