web-dev-qa-db-fra.com

Intégrer Python et C ++

J'apprends le C++ parce que c'est un langage très flexible. Mais pour des choses sur Internet comme Twitter, Facebook, Delicious et autres, Python semble une bien meilleure solution.

Est-il possible d'intégrer C++ et Python dans le même projet?

57
Nathan Campos

L'interfaçage Python avec C/C++ n'est pas une tâche facile.

Ici, je copie/colle un réponse précédente sur une question précédente pour les différentes méthodes pour écrire une extension python. Avec Boost.Python, SWIG, Pybindgen ...

  • Vous pouvez écrire vous-même une extension en C ou C++ avec Python C-API .

    En un mot: ne faites pas cela sauf pour apprendre à le faire. C'est très difficile de le faire correctement. Vous devrez incrémenter et décrémenter les références à la main et écrire beaucoup de code juste pour exposer une fonction, avec très peu d'avantages.

  • Swig :

    pro: vous pouvez générer des liaisons pour de nombreux langages de script.

    inconvénients: je n'aime pas la façon dont l'analyseur fonctionne. Je ne sais pas s'ils ont fait des progrès, mais il y a deux ans, l'analyseur C++ était assez limité. La plupart du temps, je devais copier/coller mes en-têtes .h pour ajouter des % caractères et pour donner des conseils supplémentaires à l'analyseur de swig.

    J'avais également besoin de gérer de temps en temps le Python C-API pour des conversions de type compliquées (pas si).

    Je ne l'utilise plus.

  • Boost.Python :

    pro: C'est une bibliothèque très complète. Il vous permet de faire presque tout ce qui est possible avec l'API C, mais en C++. Je n'ai jamais eu à écrire de code C-API avec cette bibliothèque. Je n'ai également jamais rencontré de bogue à cause de la bibliothèque. Le code pour les liaisons fonctionne comme un charme ou refuse de compiler.

    C'est probablement l'une des meilleures solutions actuellement disponibles si vous avez déjà une bibliothèque C++ à lier. Mais si vous n'avez qu'une petite fonction C à réécrire, j'essaierais probablement avec Cython.

    inconvénients: si vous n'avez pas de bibliothèque Boost.Python précompilée, vous allez utiliser Bjam (sorte de remplacement de make). Je déteste vraiment Bjam et sa syntaxe.

    Les bibliothèques Python créées avec B.P ont tendance à devenir obèses. Il faut également beaucoup de temps pour les compiler.

  • Py ++ : c'est Boost.Python rendu facile. Py ++ utilise un analyseur C++ pour lire votre code, puis génère automatiquement du code Boost.Python. Vous avez également un grand soutien de son auteur (non ce n'est pas moi ;-)).

    inconvénients: seuls les problèmes dus à Boost.Python lui-même.

    Modifier ce projet semble abandonné. Bien qu'il fonctionne probablement encore, il peut être préférable d'envisager de changer.

  • Pybindgen :

    Il génère le code traitant de la C-API. Vous pouvez soit décrire les fonctions et les classes dans un fichier Python, soit laisser Pybindgen lire vos en-têtes et générer des liaisons automatiquement (pour cela, il utilise pygccxml, une bibliothèque python écrit par l'auteur de Py ++).

    inconvénients: c'est un projet jeune, avec une équipe plus petite que Boost.Python. Il y a encore quelques limitations: vous ne pouvez pas exposer vos propres exceptions C++, vous ne pouvez pas utiliser l'héritage multiple pour vos classes C++.

    Quoi qu'il en soit, cela vaut la peine d'essayer!

  • Pyrex et Cython :

    Ici, vous n'écrivez pas du vrai C/C++ mais un mélange entre Python et C. Ce code intermédiaire générera un module Python régulier).

Edit 22 juillet 2013: Maintenant, Py ++ semble abandonné, je cherche maintenant une bonne alternative. J'expérimente actuellement avec Cython pour ma bibliothèque C++. Ce langage est un mélange entre Python et C. Dans une fonction Cython, vous pouvez utiliser soit Python ou des entités C/C++ (fonctions, variables, objets,. ..).

Cython est assez facile à apprendre, a de très bonnes performances et vous pouvez même éviter complètement C/C++ si vous n'avez pas à interfacer les bibliothèques C++ héritées.

Cependant, pour C++, cela pose certains problèmes. C'est moins "automagique" que Py ++, donc c'est probablement mieux pour une API C++ stable (ce qui est maintenant le cas de ma bibliothèque). Le plus gros problème que je vois avec Cython est avec le polymorphisme C++. Avec Py ++/boost: python, j'ai pu définir une méthode virtuelle en C++, la remplacer en Python et avoir la version Python appelée en C++. Avec Cython c'est toujours faisable mais vous devez explicitement utilisez l'API C-Python.

Modifier le 06/10/2017:

Il y en a un nouveau, pybind11 , similaire à Boost.Python mais avec quelques avantages potentiels. Par exemple, il utilise les fonctionnalités du langage C++ 11 pour simplifier la création de nouvelles liaisons. C'est aussi une bibliothèque uniquement en-tête, donc il n'y a rien à compiler avant de l'utiliser, et aucune bibliothèque à lier.

J'ai joué un peu avec et c'était en effet assez simple et agréable à utiliser. Ma seule crainte est que, comme Boot.Python, cela puisse entraîner un long temps de compilation et de grandes bibliothèques. Je n'ai pas encore fait de référence.

90
ascobol

Oui, c'est possible, encouragé et documenté . Je l'ai fait moi-même et j'ai trouvé que c'était très facile.

9
Otto Allmendinger

Nous utilisons swig avec beaucoup de succès dans notre produit.

Swig prend essentiellement votre code C++ et génère un wrapper python autour de lui.

3
Alan

Je recommanderais de regarder comment PyTorch fait leur intégration.

3
Andrei Pokrovsky

Manuel de référence de l'API Python/C - l'API utilisée par les programmeurs C et C++ qui souhaitent écrire des modules d'extension ou intégrer Python.

Extension et intégration de l'interpréteur Python

décrit comment écrire des modules en C ou C++ pour étendre l'interpréteur Python avec de nouveaux modules. Ces modules peuvent définir de nouvelles fonctions mais aussi de nouveaux types d'objets et leurs méthodes. Le document décrit également comment incorporer le Python dans une autre application, pour une utilisation comme langage d'extension. Enfin, il montre comment compiler et lier des modules d'extension afin qu'ils puissent être chargés dynamiquement (au moment de l'exécution) dans l'interpréteur, si le système d'exploitation sous-jacent prend en charge cette fonctionnalité.

3
gimel

Essayez Pyrex . Facilite l'écriture d'extensions C++ pour Python plus facile.

3
Brian

Regarde ça:

Extension Python avec C ou C++

"Il est assez facile d'ajouter de nouveaux modules intégrés à Python, si vous savez programmer en C. De tels modules d'extension peuvent faire deux choses qui ne peuvent pas être faites directement en Python: ils peuvent implémenter de nouveaux types d'objets intégrés et ils peuvent appeler les fonctions de la bibliothèque C et les appels système.

Pour prendre en charge les extensions, l'API Python (Application Programmers Interface) définit un ensemble de fonctions, de macros et de variables qui donnent accès à la plupart des aspects de la Python run- système de temps. L'API Python est incorporée dans un fichier source C en incluant l'en-tête "Python.h". "

http://www.python.org/doc/2.5.2/ext/intro.html

PS Il s'écrit "intégrer" :)

2
Larry Watanabe

J'ai utilisé PyCxx http://cxx.sourceforge.net/ dans le passé et j'ai trouvé que c'était très bon.

Il encapsule l'API python c de manière très élégante et le rend très simple à utiliser. Il est très facile d'écrire l'extension python en c ++. Il est fourni avec des exemples clairs afin qu'il soit facile de commencer.

J'ai vraiment aimé utiliser cette bibliothèque et je la recommande.

2
luc

Cela dépend de vos exigences de portabilité. Je me bats avec cela depuis un certain temps, et j'ai fini par encapsuler mon C++ en utilisant python API directement parce que j'ai besoin de quelque chose qui fonctionne sur des systèmes où l'administrateur n'a piraté qu'un gcc fonctionnant principalement et python installation.

En théorie, Boost.Python devrait être une très bonne option, car Boost est disponible (presque) partout. Malheureusement, si vous vous retrouvez sur un système d'exploitation avec une installation par défaut plus ancienne python (notre collaboration est bloquée avec 2.4) , vous rencontrerez des problèmes si vous essayez d'exécuter Boost.Python avec une version plus récente (nous utilisons tous Python 2.6). Puisque votre administrateur n'a probablement pas pris la peine d'installer une version de Boost correspondant à chaque python version, vous devrez le construire vous-même.

Donc, si cela ne vous dérange pas de nécessiter une configuration Boost sur chaque système sur lequel votre code s'exécute, utilisez Boost.Python. Si vous voulez du code qui fonctionnera certainement sur n'importe quel système avec Python et un compilateur C++, utilisez l'API Python).

2
Shep

Une autre façon intéressante de faire est python génération de code en exécutant python lui-même pour analyser les fichiers d'en-tête c ++. L'équipe OpenCV a réussi cette approche et maintenant ils ont fait exactement la même chose pour créer Java wrapper pour la bibliothèque OpenCV. J'ai trouvé ce nettoyeur créé Python API sans limitation provoqué par une certaine bibliothèque.

1
Tae-Sung Shin

Vous pouvez écrire extensions Python en C++. Fondamentalement Python lui-même est écrit en C et vous pouvez l'utiliser pour appeler votre code C. Vous avez un accès complet à vos objets Python. Consultez également - Boost.Python .

1
Matt Price