J'ai la tâche de "envelopper" la bibliothèque ac dans une classe python. Les documents sont incroyablement vagues à ce sujet. Il semble qu'ils s'attendent à ce que seuls les utilisateurs avancés de python implémentent des ctypes. Eh bien, je suis un débutant en python et j'ai besoin d'aide.
Une aide étape par étape serait merveilleuse.
J'ai donc ma bibliothèque c. Que fais-je? Quels fichiers dois-je mettre où? Comment importer la bibliothèque? J'ai lu qu'il pourrait y avoir un moyen de "envelopper automatiquement" en Python?
(Au fait, j'ai fait le didacticiel ctypes sur python.net et cela ne fonctionne pas. Ce qui signifie que je pense qu'ils supposent que je devrais être en mesure de remplir le reste des étapes.
En fait, c'est l'erreur que j'obtiens avec leur code:
File "importtest.py", line 1
>>> from ctypes import *
SyntaxError: invalid syntax
Je pourrais vraiment utiliser une aide étape par étape à ce sujet! Merci ~
la source
>>>
dans importtest.py? Lorsque les gens publient le code qui a>>>
sur chaque ligne, cela signifie qu'il est exécuté dans le shell interactif. Pour l'exécuter à partir d'un fichier, supprimez>>>
(c'est 3> signes et un espace) partout où il apparaît.>>>
s. Ceux-ci sont imprimés par le shell interactif et doivent être laissés en dehors de votre fichier source.>>>
dans le fichier .py! AIE! Jamais vu ça avant!Réponses:
Voici un tutoriel ctypes rapide et sale.
Tout d'abord, écrivez votre bibliothèque C. Voici un exemple simple de Hello world:
testlib.c
Maintenant, compilez-le en tant que bibliothèque partagée ( correctif mac trouvé ici ):
Ensuite, écrivez un wrapper à l'aide de ctypes:
testlibwrapper.py
Maintenant, exécutez-le:
Et vous devriez voir la sortie
Si vous avez déjà une bibliothèque en tête, vous pouvez ignorer la partie non-python du didacticiel. Assurez-vous que ctypes peut trouver la bibliothèque en la plaçant dans
/usr/lib
un autre répertoire standard. Si vous faites cela, vous n'avez pas besoin de spécifier le chemin complet lors de l'écriture du wrapper. Si vous choisissez de ne pas le faire, vous devez fournir le chemin complet de la bibliothèque lors de l'appelctypes.CDLL()
.Ce n'est pas le lieu pour un tutoriel plus complet, mais si vous demandez de l'aide pour des problèmes spécifiques sur ce site, je suis sûr que la communauté vous aidera.
PS: Je suppose que vous êtes sous Linux parce que vous avez utilisé
ctypes.CDLL('libc.so.6')
. Si vous êtes sur un autre système d'exploitation, les choses peuvent changer un peu (ou beaucoup).la source
La réponse de Chinmay Kanchi est excellente mais je voulais un exemple de fonction qui passe et retourne des variables / tableaux à un code C ++. J'ai pensé l'inclure ici au cas où cela serait utile à d'autres.
Passer et renvoyer un entier
Le code C ++ d'une fonction qui prend un entier et en ajoute un à la valeur retournée,
Enregistré en tant que fichier
test.cpp
, notez l' externe "C" requis (il peut être supprimé pour le code C). Ceci est compilé en utilisant g ++, avec des arguments similaires à la réponse de Chinmay Kanchi,Le code Python utilise à
load_library
partir de l'numpy.ctypeslib
hypothèse du chemin d'accès à la bibliothèque partagée dans le même répertoire que le script Python,Cela imprime 6 comme prévu.
Passer et imprimer une matrice
Vous pouvez également passer des tableaux comme suit, pour qu'un code C imprime l'élément d'un tableau,
qui est compilé comme avant et importé de la même manière. Le code Python supplémentaire pour utiliser cette fonction serait alors,
où nous spécifions le tableau, le premier argument vers
print_array
, comme un pointeur vers un tableau Numpy de flottants alignés, c_contiguous 64 bits et le deuxième argument comme un entier qui indique au code C le nombre d'éléments dans le tableau Numpy. Ceci est ensuite imprimé par le code C comme suit,la source
import numpy as np
. Sinon, il ne peut pas trouvernp.float64
et les autres choses.Premièrement: le
>>>
code que vous voyez dans les exemples python est un moyen d'indiquer qu'il s'agit de code Python. Il est utilisé pour séparer le code Python de la sortie. Comme ça:Ici, nous voyons que la ligne qui commence par
>>>
est le code Python, et 9 est ce qu'il en résulte. C'est exactement à quoi ça ressemble si vous démarrez un interpréteur Python, c'est pourquoi c'est fait comme ça.Vous n'entrez jamais la
>>>
pièce dans un.py
fichier.Cela règle votre erreur de syntaxe.
Deuxièmement, ctypes n'est qu'une des nombreuses façons d'encapsuler les bibliothèques Python. D' autres moyens sont SWIG , qui se penchera sur votre bibliothèque Python et générer un module d'extension C Python qui expose l'API C. Une autre façon est d'utiliser Cython .
Ils ont tous des avantages et des inconvénients.
SWIG exposera uniquement votre API C à Python. Cela signifie que vous n'obtenez aucun objet ou quoi que ce soit, vous devrez créer un fichier Python séparé pour cela. Il est cependant courant d'avoir un module appelé say "wowza" et un module SWIG appelé "_wowza" qui est le wrapper autour de l'API C. C'est une manière simple et agréable de faire les choses.
Cython génère un fichier C-Extension. Cela présente l'avantage que tout le code Python que vous écrivez est transformé en C, de sorte que les objets que vous écrivez sont également en C, ce qui peut améliorer les performances. Mais vous devrez apprendre comment il s'interface avec C donc c'est un peu plus de travail pour apprendre à l'utiliser.
Les ctypes ont l'avantage qu'il n'y a pas de code C à compiler, il est donc très agréable à utiliser pour envelopper les bibliothèques standard écrites par quelqu'un d'autre, et existe déjà dans les versions binaires pour Windows et OS X.
la source