python ctypes 回调函数_python – 带参数的Ctypes回调函数 – 堆栈内存溢出

  • Post author:
  • Post category:python


有两种方法可以做到这一点。 您的回调可以是类中的方法,并且可以访问实例化类的实例数据,也可以仅将数据附加到回调本身。 这是后者的示例和一些示例回调代码:

测试

#ifdef _WIN32

# define API __declspec(dllexport)

#else

# define API

#endif

typedef int (*CALLBACK)(int);

CALLBACK g_callback;

API void set_callback(CALLBACK cb)

{

g_callback = cb;

}

API int do_callback()

{

int sum = 0;

for(int i = 0; i < 5; ++i) // Call callback with 0,1,2,3,4 parameters.

if(g_callback)

sum += g_callback(i); // Collect and sum the callback return values.

return sum;

}

test.py

from ctypes import *

CALLBACK = CFUNCTYPE(c_int,c_int)

dll = CDLL(‘test’)

dll.set_callback.argtypes = CALLBACK,

dll.set_callback.restype = c_int

dll.do_callback.argtypes = ()

dll.do_callback.restype = c_int

@CALLBACK

def my_callback(id):

return id + my_callback.my_data # Use the extra callback data.

def init_callback(my_data):

my_callback.my_data = my_data # Simply attach the data as a variable of the callback.

dll.set_callback(my_callback)

init_callback(0)

print(dll.do_callback()) # Expect (0+0)+(1+0)+(2+0)+(3+0)+(4+0) = 10

init_callback(1)

print(dll.do_callback()) # Expect (0+1)+(1+1)+(2+1)+(3+1)+(4+1) = 15

输出量

10

15

关于示例代码的注释。 创建了callback(callbackFunc)并将其传递给lib.SetMessageCallback()但是由于该行执行后没有引用,回调被销毁。 当您尝试使用回调时,这可能会使您的系统崩溃。 对上面的回调函数使用装饰器(@CALLBACK)就像我上面所做的那样,等效于my_callback = CALLBACK(my_callback) 。 函数名称在全局级别,不会超出范围。 因此,在生成回调时请记住这一点。 将它们存储在变量中,并确保它在范围内,直到您完成它。