2013-07-31 11 views
6

Sto cercando di scrivere il codice Python per richiamare le funzioni di dll e bloccato nella funzione di seguito, che credo sia correlata alla funzione di callback typedef o al puntatore di funzione.Scrittura di caratteri in Python per la funzione di callback del puntatore di funzione in C

Ho testato il codice seguente, quando viene chiamata la funzione di callback, Python si blocca (Window notification-- python.exe ha smesso di rispondere) senza messaggi di debug.

Sono profondamente confuso, qualsiasi aiuto sarà apprezzato :)

Grazie!

C:

#ifdef O_Win32 
/** @cond */ 
#ifdef P_EXPORTS 
#define API __declspec(dllexport) 
#else 
#define API __declspec(dllimport) 
#endif // #ifdef P_EXPORTS 
/** @endcond */ 
#endif // #ifdef O_Win32 

// Type definition 
typedef void (__stdcall *StatusCB)(int nErrorCode, int nSID, void *pArg); 

//Function 
void GetStatus(StatusCB StatusFn, void *pArg); 

Python:

from ctypes import * 

def StatusCB(nErrorCode, nSID, pArg): 
    print 'Hello world' 

def start(): 
    lib = cdll.LoadLibrary('API.dll') 
    CMPFUNC = WINFUNCTYPE(c_int, c_int, c_void_p) 
    cmp_func = CMPFUNC(StatusCB) 
    status_func = lib.GetStatus 
    status_func(cmp_func) 

risposta

9

Il tipo di richiamata ha la firma errata; hai dimenticato il tipo di risultato. Sta anche recuperando i rifiuti quando la funzione termina; devi renderlo globale.

La chiamata GetStatus manca l'argomento pArg. Inoltre, quando si lavora con i puntatori, è necessario definire argtypes, altrimenti si avranno problemi su piattaforme a 64 bit. Il tipo di argomento predefinito di ctypes è C int.

from ctypes import * 

api = CDLL('API.dll') 
StatusCB = WINFUNCTYPE(None, c_int, c_int, c_void_p) 

GetStatus = api.GetStatus 
GetStatus.argtypes = [StatusCB, c_void_p] 
GetStatus.restype = None 

def status_fn(nErrorCode, nSID, pArg):   
    print 'Hello world' 
    print pArg[0] # 42? 

# reference the callback to keep it alive 
_status_fn = StatusCB(status_fn) 

arg = c_int(42) # passed to callback?  

def start():   
    GetStatus(_status_fn, byref(arg)) 
+0

Funziona! grazie mille miliardi! – genxstylez

Problemi correlati