PythoncTypes指向结构指针的指针
我在获取指向运行结构的指针时遇到问题。这是我的代码,它抛出异常“ArgumentError:Argument1::expected LP_LP_List instance而不是指向LP_LP_List的指针” 这似乎遵循了推荐的方法,但不起作用 谢谢你的帮助 对于那些不想阅读以下所有详细信息以找到解决方案的人,最后一部分应如下所示:PythoncTypes指向结构指针的指针,python,ctypes,Python,Ctypes,我在获取指向运行结构的指针时遇到问题。这是我的代码,它抛出异常“ArgumentError:Argument1::expected LP_LP_List instance而不是指向LP_LP_List的指针” 这似乎遵循了推荐的方法,但不起作用 谢谢你的帮助 对于那些不想阅读以下所有详细信息以找到解决方案的人,最后一部分应如下所示: #list_p = POINTER(List) # Not needed create = lib.DLL_CreateList create.argtypes
#list_p = POINTER(List) # Not needed
create = lib.DLL_CreateList
create.argtypes = [POINTER(POINTER(List)),]
create.restype = POINTER(List)
control = POINTER(List)()
list_p = create(byref(control))
List *create(List **control);
List *control;
List *plist;
plist = create(&control);
API听起来像是通过引用传入的指针将由create修改,因此它必须通过引用传入,返回值是新创建的列表 如果这是用“C”写的,我猜你会有这样的代码:
#list_p = POINTER(List) # Not needed
create = lib.DLL_CreateList
create.argtypes = [POINTER(POINTER(List)),]
create.restype = POINTER(List)
control = POINTER(List)()
list_p = create(byref(control))
List *create(List **control);
List *control;
List *plist;
plist = create(&control);
对于ctypes/Python,这将映射到:
create.argtypes = [POINTER(POINTER(List)),]
create.restype = POINTER(List)
control = POINTER(List)()
newlist = create(byref(control))
这个效果更好吗
编辑:
因为create会修改传入的参数并返回创建的列表,所以我会忘记返回,只保留参数:
create.argtypes = [POINTER(POINTER(List)),]
control = Pointer(List)()
create(byref(control))
对于Python API的完整性,您可以考虑编写上下文管理器,以处理调用CREATE(当上下文管理器的的末尾调用上下文管理器的
方法时)。然后,您的Python代码可能如下所示:\uuuuuu退出
with listManager as ListManager():
# do stuff with list managed by list manager
# end of with statement, listManager.__exit__ is automatically called, so that Destroy always
# gets called, even if an exception is raised - this is easier for API users than expecting them
# to write their own try-finally code, and put Destroy in the finally block
编辑:-我在Ubuntu上构建了你的DLL,并使用了上面的Python代码,看起来它毕竟是一个列表
~/dev/python$ python
Python 2.6.6 (r266:84292, Sep 15 2010, 16:22:56)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>>
>>> class List(Structure): pass
...
>>> lib = CDLL('./libdll.so')
>>> create = lib.DLL_CreateList
>>> create.argtypes = [POINTER(POINTER(List)),]
>>> create.restype = POINTER(List)
>>>
>>> control = POINTER(List)()
>>> create(byref(control))
<__main__.LP_List object at 0x7fdc0c607e60>
它以什么方式“不起作用”?我编辑了上面的内容,完全例外情况减去回溯。如果您将创建的列表作为函数返回值返回,为什么要通过引用传递列表指针?什么是“创建”真的吗?我正在用python为一个链接列表API编写单元测试,这个API是我12年前写的,被成千上万的人使用,现在每周都在下载函数创建一个可以控制所有链接列表节点的中心控制结构。其思想是向它传递一个指向控制结构指针的空指针。然后,它在内存中创建链接列表控制结构。下一次调用将把您需要的数据结构附加到控制结构,然后其他调用可以复制该结构。保留传入的参数是人们通常做的事情,但是,我也曾请求将其从函数中传递出去,但通常会被丢弃。我已经尝试过你的建议,但也不起作用。newlist=Pointer(List)()好的,我第一次一定是做错了什么。我移动了一些代码并使其正常工作。control=POINTER(List)()newlist=create(byref(control))现在可以工作了。谢谢。确实可以,正如我上面提到的,我第一次尝试它时一定是做错了什么,但现在可以工作了。再次感谢您的帮助。哇,非常感谢您的帮助。最近几个月来,这个API在FreshMeat/freecode上大受欢迎。我现在和现在都倾向于使用PythonC不再如此。然而,最近有人在DLL_AddRecord()函数中发现了一个12年前的bug,这让我想编写单元测试。再次感谢。