Envelopper C ++ avec Cython pour une utilisation à partir de Python

Remarque: les articles suivants sont obsolètes.

Pensez à utiliser pybind11.

[Accélération Python] c ++ intégré par pybind11


"Accélérer Python en fusionnant avec Cython C" De O'Reilly J'ai essayé de tracer sur Ubuntu qu'une fonction écrite en langage C ++ peut être importée et exécutée en Python. Tout d'abord, l'exemple de ce livre est sur github, alors téléchargez-le sous forme de fichier zip. https://github.com/cythonbook/examples Accédez au répertoire extrait. examples-master/08-wrapping-cxx/01-simple-example-mt_rng-class

Code source écrit en C ++ mt19937.h mt19937.cpp

Déclaration de code C externe en Cython (extension .pxd) Wrap de classe C ++ (extension .pyx)

RNG.pyx


# distutils: language = c++
# distutils: sources = mt19937.cpp

cdef extern from "mt19937.h" namespace "mtrandom":
    unsigned int N
    cdef cppclass MT_RNG:
        MT_RNG()
        MT_RNG(unsigned long s)
        MT_RNG(unsigned long init_key[], int key_length)
        void init_genrand(unsigned long s)
        unsigned long genrand_int32()
        double genrand_real1()
        double operator()()

cdef class RNG:

    cdef MT_RNG *_thisptr

    def __cinit__(self, unsigned long s):
        self._thisptr = new MT_RNG(s)
        if self._thisptr == NULL:
            raise MemoryError()

    def __dealloc__(self):
        if self._thisptr != NULL:
            del self._thisptr

    cpdef unsigned long randint(self):
        return self._thisptr.genrand_int32()

    cpdef double rand(self):
        return self._thisptr.genrand_real1()

Fichier Setup.py qui vous indique comment compiler

py.setup.py


from distutils.core import setup, Extension
from Cython.Build import cythonize

ext = Extension("RNG",
                sources=["RNG.pyx", "mt19937.cpp"],
                language="c++")

setup(name="RNG",
      ext_modules=cythonize(ext))

À partir de là, j'essaye d'interpréter Cython, mais c'est peut-être faux. Veuillez vous référer au même livre.

Déclaration de code C ++ externe en Cython (extension .pxd)

Comment écrire un fichier pxd


cdef extern from "C++Fichier d'en-tête dans" namespace "C++Espace de nom dans":
    C++Constantes définies par const static dans le fichier d'en-tête de
    unsigned int N
    cdef cppclass C++Identifiant de classe dans:
Constacteur()
Constacteur(unsigned long s)
Constacteur(unsigned long init_key[], int key_length)
C utilisé en Cython parmi les méthodes publiques++Déclaration de méthode
        void init_genrand(unsigned long s)
        unsigned long genrand_int32()
        double genrand_real1()
        double operator()()

Dans le fichier téléchargé depuis github, la déclaration du code C ++ externe en Cython est Vous avez migré vers un fichier pyx.

Ajout d'une description au fichier pyx pour spécifier qu'il s'agit d'un langage C ++ # distutils: language = c++

cdef cppclass MT_RNG:

Dans la description de bloc de, la définition de la classe et de la méthode publique dans la source de référence C ++ est décrite.

Comment écrire un fichier pyx


cdef class Identifiant de classe en Cython:

    cdef MT_RNG *_thisptr

    def __cinit__(self, unsigned long s):
Description du constructeur
C pour être enveloppé dans ce++Créez une instance de la classe de.
Le premier self de l'argument est commun au cas de la classe Python.
        self._thisptr = new MT_RNG(s)
        if self._thisptr == NULL:
            raise MemoryError()

    def __dealloc__(self):
Méthode spéciale pour nettoyer
        if self._thisptr != NULL:
            del self._thisptr

Tapez le nom de la méthode dans cpdef Cython(self,argument):
Implémentation de méthodes dans la syntaxe Cython
En cela, C déclaré par cdef extern++Les fonctions et méthodes sont disponibles.
return Valeur de retour
    cpdef unsigned long randint(self):
        return self._thisptr.genrand_int32()

    cpdef double rand(self):
        return self._thisptr.genrand_real1()

setup.Comment écrire py


from distutils.core import setup, Extension
from Cython.Build import cythonize

ext = Extension("Nom de l'extension python",
                sources=["Nom du fichier pyx", "nom de fichier cpp"],
                language="c++")

setup(name="RNG",
      ext_modules=cythonize(ext))

Différence par rapport à la version C: ext = Extension () a maintenant language = "c ++" ajouté.

Supplément: Il est également possible d'inclure des déclarations d'élément de langage de niveau C dans des fichiers pyx au lieu de fichiers pxd. Cependant, il est préférable de le conserver dans un fichier pxd séparé pour la maintenance. à titre d'essai, cdef extern from "mt19937.h" namespace "mtrandom": Même si vous extrayez le bloc en commençant par du fichier pyx vers le fichier pyd et le compilez Construction et opération réussies.

URL: Tutoriel de document Cython (traduction japonaise) http://omake.accense.com/static/doc-ja/cython/src/tutorial/index.html

Recommended Posts

Envelopper C avec Cython pour une utilisation à partir de Python
Envelopper C ++ avec Cython pour une utilisation à partir de Python
Utilisation des fonctions C ++ de python avec pybind11
Appeler C depuis Python avec DragonFFI
Conseils pour appeler Python à partir de C
Objet de tampon de tableau pouvant être utilisé avec Cython
Envelopper (partie de) la bibliothèque AtCoder en Cython pour une utilisation en Python
Utilisez Thingsspeak de Python
Utiliser fluentd de python
Utilisez MySQL depuis Python
Utilisez Logger avec Python pour le moment
Utiliser mecab avec Python 3
Utiliser DynamoDB avec Python
Utilisez Python 3.8 avec Anaconda
Utiliser python avec docker
Utiliser MySQL depuis Python
Utilisez BigQuery depuis Python.
~ Conseils pour les débutants de Python donnés avec amour par Pythonista ② ~
Utilisez mecab-ipadic-neologd de Python
Benchmarks langage C, Java, Python avec factorisation prime
Utiliser Python installé par pyenv pour l'environnement d'exécution PL / Python
Programmez avec votre smartphone n'importe où! (Recommandé pour le langage C / Python)
Utiliser l'API Trello avec python
Utiliser l'API Twitter avec Python
Utiliser TUN / TAP avec Python
Utiliser MySQL depuis Anaconda (python)
Utiliser Cython avec Jupyter Notebook
Utiliser l'API subsonique avec python3
Avec skype, notifiez avec skype de python!
Utilisez l'API e-Stat de Python
Utilisons un langage de script pour une implémentation C ++ confortable après vérification avec python
Utiliser IvyFEM (bibliothèque de méthodes d'éléments finis pour .NET) à partir de Python
[python] Remarques lors de la tentative d'utilisation de numpy avec Cython
Introduction à Python pour les utilisateurs de VBA - Appeler Python depuis Excel avec xlwings -
Obtenez des données de l'API d'analyse avec le client API Google pour python
Utilisez un langage de script pour une vie C ++ confortable-OpenCV-Port Python vers C ++ -
Python: comment utiliser async avec
Utiliser la caméra Point Grey avec Python (PyCapture2)
Utilisez vl53l0x avec RaspberryPi (python)
Créer Awaitable avec l'API Python / C
Utilisation de Rstan de Python avec PypeR
Installez Python à partir des sources avec Ansible
Appeler popcount depuis Ruby / Python / C #
Utilisez NAIF SPICE TOOL KIT avec Python
Lire et utiliser des fichiers Python à partir de Python
Ensuite, utilisez Python (Flask) pour Heroku!
Utiliser de force Google Translate à partir de python
Aide-mémoire Python (pour les expérimentés C ++)
Utiliser rospy avec virtualenv dans Python3
Résoudre ABC168 A ~ C avec Python
Exécutez Aprili depuis Python sur Orange
Exécuter du code Python à partir de l'interface graphique C #
Utiliser Azure Blob Storage à partir de Python
Utilisez l'API Flickr de Python
Comment envelopper C en Python