我正在尝试为一个名为 Virtual Paradise 的应用程序设计一个机器人,并且用于构建该机器人的 SDK 被编译到一个共享库中,因此我必须使用 ctypes。
当我使用时
import threading
...
from ctypes import CDLL, CFUNCTYPE, c_char_p, c_int, c_void_p
vp = CDLL("libvpsdk.so")
vp.vp_string.restype = c_char_p
vp.vp_int.restype = c_int
...
class bot(threading.Thread):
def initBot(self):
...
instance = vp.vp_create()
...
EventFunc = CFUNCTYPE(None)
event_chat_func = EventFunc(self.event_chat)
vp.vp_event_set(instance, 0, event_chat_func)
...
def event_chat(self):
print "Hello"
...
event_chat 被正确调用并打印“Hello”
但是当我使用这个
import threading
import chat
...
from ctypes import CDLL, CFUNCTYPE, c_char_p, c_int, c_void_p
vp = CDLL("libvpsdk.so")
vp.vp_string.restype = c_char_p
vp.vp_int.restype = c_int
...
class bot(threading.Thread):
def initBot(self):
...
instance = vp.vp_create()
...
chat.VPSDK(vp, instance)
...
聊天.py:
from ctypes import CFUNCTYPE
...
class VPSDK:
def __init__(self, vp, instance):
EventFunc = CFUNCTYPE(None)
event_chat_func = EventFunc(self.event_chat)
vp.vp_event_set(instance, 0, event_chat_func)
def event_chat(self):
print "Hello"
...
我收到错误“非法指令”
我做错了什么!?我需要使用这个单独的类,否则我的机器人的其他部分将失去功能。
最佳答案
您必须在调用包装函数的生命周期内维护对它的引用。请参阅 15.16.1.17. Callback functions 末尾的重要说明...在 Python ctypes documentation .
一种方法是使用 self.event_chat_func
来代替,在包含对象的生命周期内存储它。
此外,创建 chat.VPSDK(vp, instance)
会创建一个 chat.VPSDK
实例,该实例超出下一行的范围。您没有演示如何在第一个示例中实例化 bot
,但 VPSDK
对象的生命周期并不长。
关于Python Ctypes 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4505839/