[PYTHON] (Personal) points when using ctypes

ctypes is a standard library for calling dynamic libraries from Python. Make a note of the lessons / addictive points you learned when using it for the first time recently.

Be sure to specify restype and argtypes

When calling a function in a dynamic library, you need to specify a type that is compatible with C. (ref.) http://docs.python.jp/2/library/ctypes.html#ctypes-fundamental-data-types

This type is specified either when the function is called, or the return value / argument type is specified in advance by restype / ʻargtypes` before the call.

Type specification


from ctypes import *

#Specified at runtime
ret = test.func2(c_char_p("test"), c_char_p("test2"), c_char_p("test3"))

# restype/Specified by 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")

Since it becomes troublesome to specify at runtime as the number of calls increases, I think it is better to create a module that defines the interface of the library. Is it the same as the C header file?

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)

Specifying the pointer type of the structure

Structures are represented in the Python world by classes that inherit from ctypes.Structure. The members of the structure are specified in the __fields__ fields as an array of tuples. Tuples must be of the form (<field name>, <type>).

Structure and corresponding class


from ctypes import *

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

If you want to specify the pointer type of this structure, use the ctypes.POINTER function. (ref.)http://docs.python.jp/2/library/ctypes.html#ctypes.POINTER

Structure pointer type


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))

Specifying the pointer type of a pointer

For types that originally represent pointers, such as ctypes.c_char_p and ctypes.c_void_p, you can use the ctypes.POINTER function.

Pointer type of pointer(A type that originally represents a pointer)


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))

When using these, it is necessary to give the variable specified by ctypes.c_char_p / ctypes.c_void_p to the ctypes.byref function to get a reference.

Handle pointer type arguments of pointers


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 is already defined
arg2 = 'str2'
arg3 = 'str3'
arg4 = 'str4'
void_p_p = c_void_p(None)
char_p_p = c_char_p(None)
#If it is the following, NULL is assigned to the pointer of the pointer, so it is useless.
# void_p_p = None
# char_p_p = None

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

(Note) I don't know about the types that represent primitive types such as ctypes.c_int because I haven't used them this time. Do you use the ctypes.POINTER function twice?

Recommended Posts

(Personal) points when using ctypes
Summary when using Fabric
Precautions when using Chainer
Environment variables when using Tkinter
When using optparse with iPython
Addictive points when downloading files using boto on AWS Lambda
DEBUG settings when using Django
When using if and when using while
File structure when using serverless-python-requirements
Use configparser when using API
Small speedup when using pytorch
A memorandum when using beautiful soup
Variable scope when using internal functions
Points to note when updating to WSL2
Proxy measures when using WEB API
Precautions when using pit in Python
Precautions when using TextBlob trait analysis
Precautions when using codecs and pandas
Precautions when using the urllib.parse.quote function
[Python] Be careful when using print
Precautions when using phantomjs from python
ResourceWarning when using requests: unclosed workaround
When using MeCab with virtualenv python
Precautions when using six with Python 2.5
[VS Code] ~ Tips when using python ~
When using regular expressions in Python
Check points when MIDI does not work in a program using SDL_mixer
Organize the flow when running Django using NGINX and gunicorn (personal memo)