python 中的回调问题(ctypes)
problem with callback in python ( ctypes)
您好,我在 python 中遇到 CTYPES 问题。我已经准备好带有一些回调的 dll 库。在 swift 上一切正常,但我在 python 上遇到了一些问题。
Python:
def set_up_callback(self):
self.lib.set_callback(self.callback1)
@CFUNCTYPE(None, c_float, c_float, c_float, c_uint64)
def callback1( a, b, c, time):
print(a, b, c, time)
C++
回调声明
typedef void(*callbackType)(float, float, float, uint64_t, void*);
callbackType callback;
void* context;
c++ 初始化
void setCallback(callbackType callback, void* context) {
this->context = context;
this->callback = callback;
}
c++归纳
callback(1.5f, 2.4f, 1.3f, timestamp, context);
shared.h
extern "C" void SHARED_EXPORT set_callback(callbackType callback, void* context);
这很好用,但我想 self
在回调函数中,所以我试试这个
def set_up_callback(self):
callback_type = CFUNCTYPE(None, c_float, c_float, c_float, c_uint64)
callback = callback_type(self.callback1)
self.lib.set_callback(callback)
def callback1(self, a, b, c, time):
print(a, b, c, time)
这次尝试出现错误 Segmentation fault: 11
提前感谢您的帮助
在set_up_callback
中,callback
是一个在调用self.lib.set_callback(callback)
后超出作用域的局部变量。您必须在可以调用的生命周期内保留对 callback
的引用,因此将其存储为 class 实例的成员变量。
工作演示:
demo.cpp
#include <time.h>
#include <stdint.h>
#if defined(_WIN32)
# define API __declspec(dllexport)
#else
# define API
#endif
typedef void(*CALLBACK)(float, float, float, uint64_t, void*);
CALLBACK g_callback;
extern "C" {
API void set_callback(CALLBACK callback) {
g_callback = callback;
}
API void demo(void* context) {
if(g_callback)
g_callback(1.5f, 2.4f, 1.3f, time(nullptr), context);
}
}
demo.py
from ctypes import *
from datetime import datetime
CALLBACK = CFUNCTYPE(None,c_float,c_float,c_float,c_uint64,c_void_p)
class Demo:
def __init__(self):
self.lib = CDLL('./demo')
self.lib.set_callback.argtypes = CALLBACK,
self.lib.set_callback.restype = None
self.lib.demo.argtypes = c_void_p,
self.lib.demo.restype = None
self.set_up_callback()
def callback(self,a,b,c,timestamp,context):
print(a,b,c,datetime.fromtimestamp(timestamp),self.context)
def set_up_callback(self):
self.callback = CALLBACK(self.callback)
self.lib.set_callback(self.callback)
def demo(self,context):
self.context = context
self.lib.demo(None)
demo = Demo()
demo.demo([1,2,3])
demo.demo(123.456)
demo.demo('a context')
输出:
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 [1, 2, 3]
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 123.456
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 a context
您好,我在 python 中遇到 CTYPES 问题。我已经准备好带有一些回调的 dll 库。在 swift 上一切正常,但我在 python 上遇到了一些问题。
Python:
def set_up_callback(self):
self.lib.set_callback(self.callback1)
@CFUNCTYPE(None, c_float, c_float, c_float, c_uint64)
def callback1( a, b, c, time):
print(a, b, c, time)
C++ 回调声明
typedef void(*callbackType)(float, float, float, uint64_t, void*);
callbackType callback;
void* context;
c++ 初始化
void setCallback(callbackType callback, void* context) {
this->context = context;
this->callback = callback;
}
c++归纳
callback(1.5f, 2.4f, 1.3f, timestamp, context);
shared.h
extern "C" void SHARED_EXPORT set_callback(callbackType callback, void* context);
这很好用,但我想 self
在回调函数中,所以我试试这个
def set_up_callback(self):
callback_type = CFUNCTYPE(None, c_float, c_float, c_float, c_uint64)
callback = callback_type(self.callback1)
self.lib.set_callback(callback)
def callback1(self, a, b, c, time):
print(a, b, c, time)
这次尝试出现错误 Segmentation fault: 11
提前感谢您的帮助
在set_up_callback
中,callback
是一个在调用self.lib.set_callback(callback)
后超出作用域的局部变量。您必须在可以调用的生命周期内保留对 callback
的引用,因此将其存储为 class 实例的成员变量。
工作演示:
demo.cpp
#include <time.h>
#include <stdint.h>
#if defined(_WIN32)
# define API __declspec(dllexport)
#else
# define API
#endif
typedef void(*CALLBACK)(float, float, float, uint64_t, void*);
CALLBACK g_callback;
extern "C" {
API void set_callback(CALLBACK callback) {
g_callback = callback;
}
API void demo(void* context) {
if(g_callback)
g_callback(1.5f, 2.4f, 1.3f, time(nullptr), context);
}
}
demo.py
from ctypes import *
from datetime import datetime
CALLBACK = CFUNCTYPE(None,c_float,c_float,c_float,c_uint64,c_void_p)
class Demo:
def __init__(self):
self.lib = CDLL('./demo')
self.lib.set_callback.argtypes = CALLBACK,
self.lib.set_callback.restype = None
self.lib.demo.argtypes = c_void_p,
self.lib.demo.restype = None
self.set_up_callback()
def callback(self,a,b,c,timestamp,context):
print(a,b,c,datetime.fromtimestamp(timestamp),self.context)
def set_up_callback(self):
self.callback = CALLBACK(self.callback)
self.lib.set_callback(self.callback)
def demo(self,context):
self.context = context
self.lib.demo(None)
demo = Demo()
demo.demo([1,2,3])
demo.demo(123.456)
demo.demo('a context')
输出:
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 [1, 2, 3]
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 123.456
1.5 2.4000000953674316 1.2999999523162842 2020-04-11 11:38:44 a context