通过void *传递Python对象并返回回调

时间:2015-03-30 14:48:53

标签: python ctypes

我正在为大量使用回调的C库编写Python绑定。为了方便Python,我正在寻找一种将Python对象作为void *传递给C函数的方法,并且一旦它在Python回调中将指针返回给我,就将其转换回Python对象

首先,这是一个示例C文件:

test1.c

void call_callback(void (*callback)(void *), void *user_data)
{
    callback(user_data);
}

将其编译为名为libtest1.so的共享库。这是一个示例Python文件:

test1.py

# Create bindings (in reality done in a module)
from ctypes import *

cdll.LoadLibrary("libtest1.so")
test1 = CDLL("libtest1.so")

test1.call_callback.argtypes = [CFUNCTYPE(None, c_void_p), c_void_p]
test1.call_callback.restype = None
def call_callback(func, data):
    # Note: converting Python function to be callable from C
    callback = CFUNCTYPE(None, c_void_p)(func)
    test1.call_callback(callback, data)

# Testing:
def callback1(data):
    number = cast(data, POINTER(c_int))
    print('Callback 1 got:', number[0])

data1 = c_int(10)
call_callback(callback1, byref(data1))

所以,一切都运转正常。要发送的数据可以使用ctypes.c_int创建,并由ctypes.byref发送,然后由ctypes.cast恢复为相应的类型(ctypes.POINTER(ctypes.c_int))。

我的问题如下。在调用C函数时,我可以将任何普通的Python对象作为ctypes.c_void_p吗?如果是这样,怎么样?另外,当我在Python回调中获得指针时,如何恢复Python对象?

想象一下以下代码:

def callback2(data):
    list = c_void_p_was_really_a_python_list(data)
    print('callback 2 got:', list)

data2 = [1, 2, 3]
call_callback(callback2, convert_to_c_void_p(data2))

我基本上在寻找convert_to_c_void_pc_void_p_was_really_a_python_X函数。


兼容Python 2(> = 2.7)和Python 3的解决方案会很棒,但我也会对版本特定的答案感兴趣。

0 个答案:

没有答案