2010-12-22 5 views
1

Je suis en train de concevoir un bot pour une application appelée Virtual Paradise et le SDK qui est donné pour construire le bot est compilé dans une bibliothèque partagée, donc je dois utiliser ctypes.Python Ctypes comportement bizarre

quand j'utilise

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 est appelé correctement et imprime "Bonjour"

mais quand j'utilise cette

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

Je reçois le er ror "Instruction illégale"

Qu'est-ce que je fais de mal? Je dois utiliser cette classe séparée, sinon les autres parties de mon bot perdront des fonctionnalités.

Répondre

3

Vous devez conserver une référence à la fonction enveloppée pour la durée de vie à laquelle elle peut être appelée. Voir le Note importante ... à la fin de 15.16.1.17. Callback functions dans le Python ctypes documentation. L'une des façons est d'utiliser self.event_chat_func à la place, en le stockant pour la durée de vie de l'objet conteneur.

En outre, la création chat.VPSDK(vp, instance) crée une instance de chat.VPSDK qui est hors de portée dans la ligne suivante. Vous ne montrez pas comment bot est instancié dans le premier exemple, mais l'objet VPSDK ne vit pas très longtemps.

+0

Merci, je viens de rendre la variable "event_chat_func" globale dans "chat.py" et maintenant cela fonctionne sans aucun problème. – MetaDark