2010-12-22 120 views
1

我想設計一個名爲虛擬天堂的應用程序的機器人,並且爲構建bot而給出的SDK被編譯到共享庫中,因此我必須使用ctypes。Python 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" 
     ... 

我得到呃ror「非法指令」

我在做什麼錯誤!?我需要使用這個單獨的類,否則我的機器人的其他部分將失去功能。

回答

3

您必須在其可能被調用的生命週期中維護對被包裝函數的引用。請參閱重要注意事項...15.16.1.17. Callback functions的末尾Python ctypes documentation

一種方法是使用self.event_chat_func來替代,將其存儲在包含對象的生命週期中。

另外,創建chat.VPSDK(vp, instance)會創建一個chat.VPSDK的實例,該實例超出了下一行的範圍。您沒有演示bot在第一個示例中是如何實例化的,但VPSDK對象的活動時間不長。

+0

謝謝,我只是在「chat.py」中創建了全局變量「event_chat_func」,現在它沒有任何問題。 – MetaDark 2010-12-22 14:28:04