0
votes

Passez la fonction C comme argument de la fonction Python dans Cyron

J'ai le code suivant qui fonctionne: xxx

donc j'ai lambda_c fonction qui prend la fonction c comme argument et je ne suis pas capable de le changer ( comme il s'agit d'une wrapper sur la bibliothèque C appuyée par une autre équipe).

Ce que je veux faire, c'est écrire un wrapper: xxx

mais cela jette une erreur:

Impossible de convertir l'objet Python en 'Function_Type'

J'ai aussi essayé de Cast Func ( Retour Lambda_c ( Func, E, F) ) Mais a eu une erreur:

Les objets Python ne peuvent pas être couplés aux pointeurs de types primitifs

L'idée derrière ceci est la suivante: tout utilisateur sera en mesure d'écrire sa propre fonction en Cython, de la compiler puis d'importer et de transmettre sa fonction à PYCLASS () .py_wrap méthode.

est-il même possible d'importer une fonction pure C et de le transmettre en tant que paramètre avec Cyron?

J'ai aussi vu Pass Cython Fonctions via l'interface Python mais contrairement à la solution là-bas, je ne suis pas capable de changer lambda_c Functon et transformez-le en une classer. De plus, lambda_c ne prend que des fonctions de certains types ( fonction_type dans notre exemple)


2 commentaires

Vous ne pouvez pas transmettre un pointeur comme argument à une fonction def, uniquement à CDEF.


@ead est-il passable de passer le pointeur dans CDEF PY_WRAP (FUNC, E, F) Méthode de classe pyclass ?


3 Réponses :


0
votes

Merci à @ead, j'ai changé de code un peu et le résultat me satisfait:

cdef class PyClass:
    cdef void py_wrap(self, function_type func, e, f):
        print(lambda_c(func, e, f))

PyClass().py_wrap(mult, 5, 5)


1 commentaires

Une façon que vous puissiez exposer le pointeur de fonction sur Python serait d'envelopper ce pointeur de fonction dans une classe CDEF à la place. Une autre option pourrait être d'utiliser l'API de capsule de Python pour envelopper le pointeur de la fonction à la place. Vous voudrez peut-être jeter un coup d'œil à SciPy's Lowlevelcallable pour une inspiration.



1
votes

Si vous voulez transmettre un python arbitraire appelable appelable en tant que pointeur de fonction C, il ne fonctionne pas - il n'y a aucun moyen de le faire dans la norme C (et il est donc impossible à Cyton de générer le code). Il y a une solution de contournement très hackys impliquant CTYPES (qui peut effectuer une génération de code d'exécution que je trouverai des liens si nécessaire. Cependant, je ne le recommande pas vraiment.

Si vous êtes heureux pour votre Utilisateurs à écrire CDEF Fonctions de Cython (la question implique que vous êtes), vous pouvez simplement construire sur ma réponse à Votre question hier .

  1. Écrivez une classe d'enveloppe appropriée (vous devez simplement modifier le type de pointeur de la fonction) - Ceci est divisé entre vos fichiers .pxd et .pyx que vous écrivez. < / li>

  2. avez vos utilisateurs CIMPORT IT, puis utilisez-le pour exposer leur CDEF CDSEC sur Python: XXX

  3. Changement pyclass pour prendre Funcwrapper comme argument: XXX

  4. Vos utilisateurs peuvent ensuite utiliser leurs fonctions compilées de Python: XXX


    Vraiment tout cela se fait consiste à utiliser un petit wrapper Python pour vous permettre de passer autour d'un type que Python ne peut normalement gérer. Vous êtes assez limité dans ce qu'il est possible de faire avec ces pointeurs de fonction emballés (par exemple, ils doivent doivent être mis en place dans Cyron) mais cela donne une poignée pour les sélectionner et les transmettre.


2 commentaires

Merci beaucoup! Un détail de plus, pour autant que je sache, je peux compiler le colis principal et que CIMPORT d'en installer l'un, le FunCwrapper et en entraîne un nouveau. J'ai essayé cela, mais obtenez 'wrap.pxd' non trouvé lorsque vous essayez de cimport wrap. J'ai ajouté packages = ['wrap'] à la fonction de configuration de seugools mais cela n'a pas aidé


Je pense que la principale chose est pour wrap.pxd sur le chemin Python. En tant que preuve de concept, essayez de créer votre autre package dans le même répertoire que wrap et cela devrait fonctionner. Si vous utilisez un répertoire différent, le cimport doit refléter cela. C'est toujours quelque chose qui est un peu difficile à faire malheureusement et je ne comprends pas la meilleure pratique que bien



1
votes

Je ne suis pas sûr que si vous êtes autorisé à modifier le type de pointeur de fonction de xxx pré>

à p> xxx pré>

mais c'est généralement le Les fonctions de rappel des voies sont implémentées dans C. Void * code> paramètre func_d code> à la fonction contient les données fournies par l'utilisateur sous n'importe quel formulaire. Si la réponse est oui, vous pouvez avoir la solution suivante. P>

Premièrement, créez le fichier de définition suivant en Cython pour révéler votre API C à d'autres utilisateurs de Cyron: P>

print(call_me(lambda x, y: x - y, 5, 6))


0 commentaires