Странное поведение Python Ctypes - PullRequest
1 голос
/ 22 декабря 2010

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

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 Ответ

3 голосов
/ 22 декабря 2010

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

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

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

...