如何在使用ctypes.pythonapi.PyCapsule\u New时设置name参数

2024-06-08 17:00:06 发布

您现在位置:Python中文网/ 问答频道 /正文

如何通过ctypes将胶囊的名称传递到PyCapsule_New的第二个参数中

我尝试了以下方法,但似乎出现了问题:

capsule = ctypes.pythonapi.PyCapsule_New(b'data', b'abcdef.ghijkl', None)
capsule = ctypes.pythonapi.PyCapsule_New(b'data', ctypes.create_string_buffer(b"abcdef.ghijkl"), None)
capsule = ctypes.pythonapi.PyCapsule_New(b'data', ctypes.c_chap_p(b"abcdef.ghijkl"), None)

例如,未正确设置胶囊的名称:

>>> import ctypes
>>> ctypes.pythonapi.PyCapsule_New.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p]
>>> ctypes.pythonapi.PyCapsule_New.restype = ctypes.py_object
>>>
>>> capsule = ctypes.pythonapi.PyCapsule_New(b'data', b'abcdef.ghijkl', None)
>>>
>>> capsule
<capsule object "" at 0xf7102f98>
>>> capsule
<capsule object "e" at 0xf7102f98>
>>> capsule
<capsule object "���capsule
<capsule object "" at 0xf7102f98>
>>> capsule
<capsule object "e" at 0xf7102f98>
>>> capsule
<capsule object "e" at 0xf7102f98>
>>> capsule
<capsule object "���

如果我使用ctypes.create_string_buffer(b"abcdef.ghijkl")

>>> capsule = ctypes.pythonapi.PyCapsule_New(b'data', ctypes.create_string_buffer(b"abcdef.ghijkl"), None)
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>

奇怪的是,如果我做一个返回一个胶囊的C扩展,我可以使用ctypes提取它的名称,它可以工作:

>>> capsule_from_c_ext = mycext.capsule()
>>> ctypes.pythonapi.PyCapsule_GetName.restype = ctypes.c_char_p
>>> ctypes.pythonapi.PyCapsule_GetName.argtypes = [ctypes.py_object]
>>> name = ctypes.pythonapi.PyCapsule_GetName(capsule_from_c_ext)
>>> name
b"abcdef.ghijkl"
>>> type(name)
<class 'bytes'>
>>> assert name == b"abcdef.ghijkl"
>>>
>>> capsule = ctypes.pythonapi.PyCapsule_New(b'data', name, None)
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23c20>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23c20>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23c20>
>>>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23c20>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23c20>

此外,如果使用较短的名称,如b'name',它似乎工作正常


Tags: name名称nonepythonapinewdataobjectcreate
1条回答
网友
1楼 · 发布于 2024-06-08 17:00:06

我从docs得到了一个提示:

The name string may either be NULL or a pointer to a valid C string. If non-NULL, this string must outlive the capsule. (Though it is permitted to free it inside the destructor.)

首先创建一个名为的变量,然后调用它,似乎可以:

>>> import ctypes
>>> ctypes.pythonapi.PyCapsule_New.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p]
>>> ctypes.pythonapi.PyCapsule_New.restype = ctypes.py_object
>>> name = b'abcdef.ghijkl'
>>> capsule = ctypes.pythonapi.PyCapsule_New(b'data', name, None)
>>>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23bd8>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23bd8>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23bd8>
>>> capsule
<capsule object "abcdef.ghijkl" at 0xf6f23bd8>

您可以证明不需要释放name变量:

del name
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>
>>> capsule
<capsule object "" at 0xf7102fb0>

相关问题 更多 >