title: How can I get methods to work as callbacks with python ctypes?
body: <p>I have an C api that i'm interfacing with the python ctypes package.  Everything works well, except this little tidbit.</p>
  
  <p>To register functions as callbacks to some notifications, i call this function :</p>
  
  <pre><code>void RegisterNotifyCallback( int loginId, int extraFlags, void *(*callbackFunc)(Notification *))
  </code></pre>
  
  <p>so in python my code looks like :</p>
  
  <pre><code>CALLBACK = ctypes.CFUNCTYPE(None, ctypes.POINTER(Notification))
  func = CALLBACK(myPythonCallback)
  myLib.RegisterNofityCallback(45454, 0, func)
  </code></pre>
  
  <p>If the value of myPythonCallback is a FunctionType (i.e. not a method), it works fine and calls the callback function with the correct parameters.  If it's a MethodType, it still calls the method but then blows up with a segfault once the method is finished.</p>
  
  <p><em>edit</em></p>
  
  <p>To clarify, when i say function type i mean that myPythonCallback is defined as a function,</p>
  
  <pre><code>def myPythonCallback(Notification):
      ...do something with the Notification object i get passed in
  </code></pre>
  
  <p>When i say it's a MethodType, i mean a class method :</p>
  
  <pre><code>class MyClass(object):
      def myPythonCallback(self, Notification):
          ...do something with Notification
  </code></pre>
  
  <p>It blows up on the second type.</p>
  
  <p>Is there an easy away around this ?  Or can someone offer me an explanation as to why this is happening ?</p>
  
  <p>Many thanks,
  Al.</p>
  
  <p><em>edit</em></p>
  
  <p>Digging a bit further with GDB gives me this :</p>
  
  <pre><code>Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 1544567712 (LWP 5389)] 0x555ae962 in instancemethod_dealloc (im=0x558ed644) at Objects/classobject.c:2360 2360    Objects/classobject.c: No such file or directory.
          in Objects/classobject.c (gdb) backtrace
  #0  0x555ae962 in instancemethod_dealloc (im=0x558ed644) at Objects/classobject.c:2360
  #1  0x555f6a61 in tupledealloc (op=0x5592010c) at Objects/tupleobject.c:220
  #2  0x555aeed1 in instancemethod_call (func=0x558db8ec, arg=0x5592010c, kw=0x0) at Objects/classobject.c:2579
  #3  0x5559aedb in PyObject_Call (func=0x558db8ec, arg=0x5592c0ec, kw=0x0) at Objects/abstract.c:2529
  #4  0x5563d5af in PyEval_CallObjectWithKeywords (func=0x558db8ec, arg=0x5592c0ec, kw=0x0) at Python/ceval.c:3881
  #5  0x5559ae6a in PyObject_CallObject (o=0x0, a=0x0) at Objects/abstract.c:2517
  </code></pre>
  
  <p>and the value passed into instancemethod_dealloc is :</p>
  
  <pre><code>(gdb) x 0x558ed644 0x558ed644:     0x00000000
  </code></pre>
  
  <p>Do you reckon this is fixable ?</p>