[PYTHON] Points (personnels) lors de l'utilisation de ctypes

ctypes est une bibliothèque standard pour appeler des bibliothèques dynamiques à partir de Python. Notez les leçons / points auxquels vous étiez accro lorsque vous l'utilisiez pour la première fois récemment.

Assurez-vous de spécifier les types restype et arg

Lors de l'appel d'une fonction dans une bibliothèque dynamique, vous devez spécifier un type compatible avec C. (ref.) http://docs.python.jp/2/library/ctypes.html#ctypes-fundamental-data-types

Ce type est spécifié soit lorsque la fonction est appelée, soit la valeur de retour / le type d'argument est spécifié à l'avance par restype / ʻargtypes` avant l'appel.

Spécification de type


from ctypes import *

#Spécifié au moment de l'exécution
ret = test.func2(c_char_p("test"), c_char_p("test2"), c_char_p("test3"))

# restype/Spécifié par argtypes
test.func2.restype = c_char_p
test.func2.argtypes = (c_char_p, c_char_p, c_char_p)
ret = test.func2("test", "test2", "test3")

Puisqu'il devient gênant de spécifier à l'exécution au fur et à mesure que le nombre d'appels augmente, je pense qu'il est préférable de créer un module qui définit l'interface de la bibliothèque. Est-ce le même que le fichier d'en-tête C?

interface.py


from ctypes import *

test.func1.restype = c_int
test.func2.argtypes = (None)

test.func2.restype = c_char_p
test.func2.argtypes = (c_char_p, c_char_p, c_char_p)

Spécifier le type de pointeur de la structure

Les structures sont représentées dans le monde Python par des classes qui héritent de ctypes.Structure. Les membres de la structure sont spécifiés dans les champs __fields__ comme un tableau de taples. Le taple doit être de la forme (<nom du champ>, <type>).

Structure et classe correspondante


from ctypes import *

class JSON_T(Structure):
    __fields__ = [('type', c_int), ('refcount', c_size_t)]

Si vous souhaitez spécifier le type de pointeur de cette structure, utilisez la fonction ctypes.POINTER. (ref.)http://docs.python.jp/2/library/ctypes.html#ctypes.POINTER

Type de pointeur de structure


from ctypes import *

class JSON_T(Structure):
    __fields__ = [('type', c_int), ('refcount', c_size_t)]

test.func3.restype = c_char_p
test.func3.argtypes = (c_void_p, c_char_p, c_char_p, c_char_p, POINTER(JSON_T))

Spécification du type de pointeur du pointeur

Pour les types qui représentent à l'origine des pointeurs, tels que ctypes.c_char_p et ctypes.c_void_p, vous pouvez utiliser la fonction ctypes.POINTER.

Type de pointeur de pointeur(À l'origine un type qui représente un pointeur)


from ctypes import *

test.func4.restype = c_char_p
test.func4.argtypes = (c_void_p, c_char_p, c_char_p, c_char_p, POINTER(c_void_p), POINTER(c_char_p))

Lors de leur utilisation, il est nécessaire de donner la variable spécifiée dans ctypes.c_char_p / ctypes.c_void_p à la fonction ctypes.byref pour obtenir une référence.

Gérer les arguments de type pointeur des pointeurs


from ctypes import *

test.func4.restype = c_char_p
test.func4.argtypes = (c_void_p, c_char_p, c_char_p, c_char_p, POINTER(c_void_p), POINTER(c_char_p))

#arg1 est déjà défini
arg2 = 'str2'
arg3 = 'str3'
arg4 = 'str4'
void_p_p = c_void_p(None)
char_p_p = c_char_p(None)
#S'il est en dessous, NULL est assigné au pointeur du pointeur, il est donc inutile.
# void_p_p = None
# char_p_p = None

test.func4(arg1, arg2, arg3, arg4, byref(void_p_p), byref(char_p_p))

(Note) Je ne connais pas les types qui représentent des types primitifs tels que ctypes.c_int car je ne les ai pas utilisés cette fois. Utilisez-vous la fonction ctypes.POINTER deux fois?

Recommended Posts

Points (personnels) lors de l'utilisation de ctypes
Résumé lors de l'utilisation de Fabric
Précautions lors de l'utilisation de Chainer
Variables d'environnement lors de l'utilisation de Tkinter
Lors de l'utilisation d'optparse avec iPython
Points addictifs lors du téléchargement de fichiers à l'aide de boto sur AWS Lambda
Paramètres de DEBUG lors de l'utilisation de Django
Lors de l'utilisation si et lors de l'utilisation pendant
Structure de fichier lors de l'utilisation d'exigences python sans serveur
Utilisez configparser lors de l'utilisation de l'API
Un mémorandum lors de l'utilisation d'une belle soupe
Portée variable lors de l'utilisation des fonctions internes
Points à noter lors de la mise à jour vers WSL2
Contre-mesures contre le proxy lors de l'utilisation de l'API WEB
Précautions lors de l'utilisation de Pit avec Python
Précautions lors de l'utilisation de l'analyse des traits TextBlob
Précautions lors de l'utilisation de codecs et de pandas
Précautions lors de l'utilisation de la fonction urllib.parse.quote
[Python] Soyez prudent lorsque vous utilisez print
Précautions lors de l'utilisation de phantomjs de python
ResourceWarning lors de l'utilisation de requêtes: solution de contournement non fermée
Lors de l'utilisation de MeCab avec python dans virtualenv
Précautions lors de l'utilisation de six avec Python 2.5
Lors de l'utilisation d'expressions régulières en Python
Vérifier les points lorsque MIDI ne fonctionne pas dans un programme utilisant SDL_mixer
Organisez le flux lors de l'exécution de Django en utilisant NGINX et gunicorn (mémo personnel)