Assigning Python function to ctypes pointer variable -


i have following c source compile dll:

int (*pfuncextb)(int a, int b);  int funcb(int a, int b) {     return funcextb(a, b); }  int funcextb(int a, int b) {     return pfuncextb(a, b); } 

what want make pfuncextb "point" python function, in python:

from ctypes import *  def add(a, b):     return + b  mutdll = cdll.loadlibrary("my.dll")  pfuncextb = (pointer(cfunctype(c_int, c_int, c_int))).in_dll(mutdll, 'pfuncextb')  funcb = mutdll.funcb funcb.argtypes = [c_int, c_int] funcb.restype = c_int  pfuncextb.contents = cfunctype(c_int, c_int, c_int)(add)  print funcb(3 , 4) 

after expect following call return 7

print funcb(3, 4) 

but get:

traceback (most recent call last): .................. print funcb(3, 4) windowserror: exception: access violation reading 0x00000001 

so doing wrong here? possible have python function "assigned" ctypes pointer-to-function variable?

edit: after seeing mark tolonen's workaround (a set function pointer function variable written in c), found why didn't work me when tried it.

this not work:

set(cfunctype(c_int,c_int,c_int)(add)) print funcb(2, 3) 

while works:

callback = cfunctype(c_int,c_int,c_int)(add) set(callback) print funcb(2, 3) 

where set c function assigns pointer-to-function argument global in mark's answer. pointed out answer lays in docs:

important note callback functions: make sure keep references cfunctype() objects long used c code. ctypes doesn’t, , if don’t, may garbage collected, crashing program when callback made.

the correct type of global variable in python cfunctype(c_int,c_int,c_int) (no pointer()), don't see method change value of variable once have it. if can add set function can work:

c

typedef int (*func)(int,int);  __declspec(dllexport) func pfuncextb;  __declspec(dllexport) void set(func f) {     pfuncextb = f; }  int funcextb(int a, int b) {     return pfuncextb(a, b); }  __declspec(dllexport) int funcb(int a, int b) {     return funcextb(a, b); } 

python

from ctypes import *  func = cfunctype(c_int,c_int,c_int)  @func def add(a, b):     return + b  mutdll = cdll.loadlibrary('x')  mutdll.set.argtypes = [func] mutdll.set.restype = none  mutdll.set(add) # set global variable  pfuncextb = func.in_dll(mutdll,'pfuncextb') print(pfuncextb(1,2)) # -> 3  funcb = mutdll.funcb funcb.argtypes = [c_int, c_int] funcb.restype = c_int  print(funcb(3 , 4)) # -> 7 

note not work:

pfuncextb = pointer(func).in_dll(mutdll,'pfuncextb') pfuncextb.contents(1,2) # exception! 

Comments

Popular posts from this blog

how to insert data php javascript mysql with multiple array session 2 -

multithreading - Exception in Application constructor -

windows - CertCreateCertificateContext returns CRYPT_E_ASN1_BADTAG / 8009310b -