2017-07-11 2 views
-1

J'ai un fichier C qui est enveloppé avec swig. Ce fichier C contient une API avec un pointeur de fonction en tant qu'argument (illustré ci-dessous).Interopérabilité entre les types ctypes et swig pour python

example.c

int binary_op (int a, int b, int (*op)(int,int)) 
{ 
    return (*op)(a,b); 
} 

Je mapper une fonction à l'argument de pointeur à condition que la fonction de mappage est défini en même fichier en utilisant rasade. Mais la fonction de mappage est définie dans un autre fichier C qui est encapsulé avec Ctypes.

testing.c

int add_int(int a, int b){ 
    return a+b; 
} 

En Python, j'importé module généré de rasade et appelle l'API avec ctypes générée par la fonction de mappage, elle a entraîné une erreur.

Dans testfile.py

import example # Module generated by swig 

from ctypes import * 
wrap_dll = CDLL('testing.dll') # testing.dll is generated with File_2.c 

# Mapping function 'add_int' to argument in 'binary_op' 
example.binary_op(3,4,wrap_dll.add_int) 

L'erreur indiqué est un type d'argument ne correspond pas à.

TypeError: in method 'binary_op', argument 3 of type 'int (*)(int,int)' 
+0

Nous avons une erreur, pas de code et pas de question. Un sur trois pour un [mcve], essayez de faire mieux. – Anthon

+0

Rechercher ici pour le rappel, SWIG et Python et vous trouverez quelque chose que vous pouvez utiliser. C'est là –

+0

@JensMunk: J'ai beaucoup cherché calme mais rien ne semble lié. Toute aide serait appréciée au cas où vous pourriez me guider vers des choses connexes. Merci –

Répondre

0

J'ai créé une fonction ctypes comme ci-dessous en python:

py_callback_type = CFUNCTYPE(c_void_p, c_int, c_int) 

où le type de retour et le type d'arguments ressemble à l'argument pointeur de fonction. Maintenant, j'ai enveloppé la fonction de mappage 'add' à la fonction ctypes ci-dessus.

f = py_callback_type(add) 

Et enfin, je Casted la fonction enveloppée avec le type de retour comme pointeur et le « .value » donne l'adresse de la fonction de pointeur enveloppé.

f_ptr = cast(f, c_void_p).value 

Puis dans le fichier d'interface rasade, en utilisant typemaps, j'ai changé l'argument pointeur comme ci-dessous:

extern int binary_op (int a, int b, int INPUT);

Maintenant, quand je la carte la fonction du pointeur, l'adresse du mappage La fonction sera transmise sous la forme d'un entier INPUT à la fonction binary_op. Puisque l'argument est un pointeur, la fonction dans l'adresse sera mappée.

example.binary_op(4,5,f_ptr) ==> 9 //mapped function is 'add(int a, int b)' --> returns a+b