To clarify Thomas Heller's answer:
- The callback protocol must specify
c_void_pfor the context parameter - Argipts for a library function must point
py_objectfor a context parameter - This function should be called using
py_object(my_python_context_object) - Python py_object :
cast(context, py_object).value
. C DLL:
#include <windows.h>
BOOL APIENTRY DllMain(HMODULE, DWORD, LPVOID) {
return TRUE;
}
typedef int (*FLUFFYBUNNY_CALLBACK)(void *context);
__declspec(dllexport) int FluffyBunny(FLUFFYBUNNY_CALLBACK cb, void *context) {
int result = 0;
int count = 0;
if (cb) {
while (result == 0) {
result = (*cb)(context);
++count;
}
}
return count;
}
Python, DLL:
from ctypes import *
class Rabbit:
def __init__(self):
self.count = 0
FLUFFYBUNNY_CALLBACK = CFUNCTYPE(c_int, c_void_p)
FluffyBunny_dll = CDLL('FluffyBunny.dll')
FluffyBunny = FluffyBunny_dll.FluffyBunny
FluffyBunny.restype = c_int
FluffyBunny.argtypes = [FLUFFYBUNNY_CALLBACK, py_object]
def _private_enumerateBunnies(context):
furball = cast(context, py_object).value
if furball:
furball.count += 1
print 'furball.count =', furball.count
return 0 if (furball.count < 10) else -1
else:
return -1
enumerateBunnies = FLUFFYBUNNY_CALLBACK(_private_enumerateBunnies)
print 'no context info...'
result = FluffyBunny(enumerateBunnies, None)
print 'result=', result
print 'instance of Rabbit as context info...'
furball = Rabbit()
result = FluffyBunny(enumerateBunnies, py_object(furball))
print 'result=', result