ctypes

时间:2015-10-18 15:12:54

标签: python class pyqt ctypes typeerror

所以我不能完全确定如何提出这个问题,因为我正在与使用ctypes的其他人的代码http://pb.lericson.se/p/FpbYhX/进行交互,我无法做到这一点找到任何其他答案(这很接近: How can I get methods to work as callbacks with python ctypes?)。无论如何,这就是它。

所以我想在QThread类中运行上面的代码,这样我就可以将带有相关信息的pyqtSignal传递给我的主程序,但我无法弄清楚如何克服以下错误:

ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: expected CFunctionType instance instead of instance method

我真的只知道python,并且之前还没有与cTypes进行过互动。下面是绘制此代码的更广泛的类(这基本上只是我将链接文件中的大部分代码复制到QThread类中)。问题从底部向上发生17行。据我所知,python对我使用&#34; self.my_callback&#34;不满意。在&#34; self.MTRegisterContactFrameCallback&#34;因为my_callback是一个实例方法。这一切都很好,但是我如何将这个实例方法变成一个CFunctionType,同时仍然保持在我的类中?

class Handler(QThread):
  trackPadTouched = pyqtSignal(str)
  def __init__(self, parent=None):
    super(Handler, self).__init__(parent)
    self.parent = parent
    print self.parent
    global MTFunctions
    MTFunctions = MTFunctions(parent=self)
    self.parent = parent
    CFArrayRef = ctypes.c_void_p
    CFMutableArrayRef = ctypes.c_void_p
    CFIndex = ctypes.c_long

    self.MultitouchSupport =     ctypes.CDLL("/System/Library/PrivateFrameworks/MultitouchSupport.framework/MultitouchSupport")

    self.CFArrayGetCount = self.MultitouchSupport.CFArrayGetCount
    self.CFArrayGetCount.argtypes = [CFArrayRef]
    self.CFArrayGetCount.restype = CFIndex

    self.CFArrayGetValueAtIndex = self.MultitouchSupport.CFArrayGetValueAtIndex
    self.CFArrayGetValueAtIndex.argtypes = [CFArrayRef, CFIndex]
    self.CFArrayGetValueAtIndex.restype = ctypes.c_void_p

    MTDeviceCreateList = self.MultitouchSupport.MTDeviceCreateList
    MTDeviceCreateList.argtypes = []
    MTDeviceCreateList.restype = CFMutableArrayRef
    MTDataRef = ctypes.POINTER(MTData)



    MTDeviceRef = ctypes.c_void_p

    self.MTRegisterContactFrameCallback = self.MultitouchSupport.MTRegisterContactFrameCallback
    self.MTRegisterContactFrameCallback.argtypes = [MTDeviceRef, ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int, MTDataRef, ctypes.c_int, ctypes.c_double, ctypes.c_int)]
    self.MTRegisterContactFrameCallback.restype = None

    MTDeviceStart = self.MultitouchSupport.MTDeviceStart
    MTDeviceStart.argtypes = [MTDeviceRef, ctypes.c_int]
    MTDeviceStart.restype = None


    devices = self.MultitouchSupport.MTDeviceCreateList()
    num_devices = self.CFArrayGetCount(devices)
    print "num_devices =", num_devices
    for i in xrange(num_devices):
        device = self.CFArrayGetValueAtIndex(devices, i)
        print "device #%d: %016x" % (i, device)
        self.MTRegisterContactFrameCallback(device, self.my_callback)
        self.MTDeviceStart(device, 0)

  def my_callback(self, device, data_ptr, n_fingers, timestamp, frame):
    #print threading.current_thread(), device, data_ptr, n_fingers, timestamp, frame
    for i in xrange(n_fingers):
        data = data_ptr[i]
        d = [data_ptr[i].normalized.position.x * 100, data_ptr[i].normalized.position.y * 100]
        self.handler(i, d, n_fingers)
    return 0

def main():
    app = QtGui.QApplication(sys.argv)
    ex = Handler()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main() 

1 个答案:

答案 0 :(得分:0)

完全未经测试,但试试这个:

MTContactCallbackFunction = ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_int,
                                MTDataRef, ctypes.c_int,
                                ctypes.c_double, ctypes.c_int)

class Handler(QThread):
  trackPadTouched = pyqtSignal(str)
  def __init__(self, parent=None):
    ...
    self.MTRegisterContactFrameCallback.argtypes = [MTDeviceRef, MTContactCallbackFunction]
    ...

  @MTContactCallbackFunction
  def my_callback(device, data_ptr, n_fingers, timestamp, frame):
    ...