我正在尝试使用Cython包装DLL中定义的一些函数,难点在于这些函数的许多函数都使用指针void *,这里是函数原型的一个例子:
---------------"header.h"-----------------------
typedef void* HANDLE
int open(HANDLE* a_handle_pointer , int open_mode)
int use(HANDLE a_handle, int usage_mode )
C中的用法示例是:
---------------"main.c" -----------------
#include"header.h"
HANDLE my_handle ;
int results ;
if(open(&my_handle ,1) == 0) /* open a handle with mode 1 */
{
printf ("failed to open \n);
return 0;
}
else printf("open success \n");
use(handle , 2); /* use handle (opened with open) in mode 2 */
正如你所说的,除非Handle已经使用“open”函数打开,否则“Use”函数无法执行某些操作,这使得它在Python / cython中令人困惑
以下是我在Cython中定义我的函数“open”的方法(几个试验之一)
from libc.stdint cimport uintptr_t
cdef extern from "header.h":
ctypedef void* HANDLE
int open(HANDLE* a_handle_pointer , int open_mode)
def Open( uintptr_t a_handle_pointer , int open_mode)
return open(<HANDLE*> a_handle_pointer , open_mode)
我试图将void *指针转换为uintptr_t,正如有些人所说,但仍然会收到错误:
" TypeError: an integer is required " when calling the function.
>>>from my_module import open
>>>open (handle , 1)
我该怎么做才能解决这个问题?
我想知道如何使用void*
或void**
类型的参数从Python调用函数?
答案 0 :(得分:1)
在Python本身编写模块/绑定是一个坏的想法,特别是如果涉及指针。你应该在C中用这样的东西来做... 警告:这是CPython 3+特有的。 CPython 2扩展的编码方式不同! BTW :将您的"query": {
"multi_match": {
"query": "Testing 1 2 3",
"fields": ["title", "description"]
},
"aggs": {
"Topics": {
"terms": {
"field": "topics.id",
"size": 15
}
}
}
}
函数重命名为open
,因为它与POSIX&#39; open(3)
冲突。
load
为了构建和安装扩展程序see the docs on distutils
。
答案 1 :(得分:1)
您需要将指针包装在Cython / Python对象中,然后将该对象的实例传递给open和use函数的Python版本。请查看问题Wrapping custom type C++ pointer in Cython,了解如何在Cython中包装和传递指针。我在那里提供的答案也适用于void
- 指针。
除非您确实希望将C-API尽可能未经修改地映射到Python,否则您还应该考虑为Python界面使用不同的,可能是面向对象的设计。例如,您可以将调用open()
放入包含HANDLE
指针的Python类的构造函数中,引发错误异常并使use()
成为该类的实例方法。这样就可以防止错误使用单位化指针和整数返回值来指示Python程序员可能意外的错误。