Странное поведение Python Ctypes

Я пытаюсь спроектировать бота для приложения под названием 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 вызывается правильно и печатает "Привет"

но когда я использую это

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)
        ...

Chat.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"
        ...

Я получаю сообщение об ошибке "Недопустимая инструкция"

Что я делаю неправильно!? Мне нужно использовать этот отдельный класс, иначе другие части моего бота потеряют функциональность.

1 ответ

Решение

Вы должны поддерживать ссылку на упакованную функцию в течение всего срока ее вызова. См. Важное примечание... в конце 15.16.1.17. Функции обратного вызова в документации по Python ctypes.

Одним из способов является использование self.event_chat_func вместо этого, сохраняя его в течение времени жизни содержащего объекта.

Кроме того, создавая chat.VPSDK(vp, instance) создает экземпляр chat.VPSDK это выходит за рамки следующей строки. Вы не демонстрируете, как bot создается в первом примере, но VPSDK объект не живет очень долго

Другие вопросы по тегам