如何包装带有void *指针的C函数?

时间:2016-03-17 00:30:08

标签: python c dll cython

我正在尝试使用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调用函数?

2 个答案:

答案 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程序员可能意外的错误。