Python ctypes

ctypes

  • http://python.net/crew/theller/ctypes/
  • standard python package for dll loading
  • 3 loading methods
    • cdll : standard cdecl calling convention
    • windll : stdcall calling convention
    • oledll : stdcall calling convention, and assumes the functions return a Windows HRESULT error code

Usage Sample (GSL library)

>>> from ctypes import *
>>> gsl = cdll.LoadLibrary("libgsl") # MUST import as CDLL not WinDLL or others
>>> gsl.gsl_sf_cos
<_FuncPtr object at 0x02FF4300>
>>> gsl.gsl_sf_cos.restype
<class 'ctypes.c_long'>
>>> gsl.gsl_sf_cos.restype = c_double # MUST return type conversion
>>> gsl.gsl_sf_cos(c_double(0)) # MUST input type conversion
1.0
>>> gsl.gsl_sf_cos(c_double(1))
0.54030230586813977
>>> gsl.gsl_sf_cos(c_double(3))
-0.98999249660044542
>>> gsl.gsl_sf_cos(c_double(3.14))
-0.9999987317275395
>>> gsl.gsl_sf_cos(c_double(3.141592))
-0.99999999999978639

C Structure data conversion

buffer(a)[:]

  • convert string pointer to c structure

ctypes.memmove(ctypes.addressof(a), bytes, min(len(bytes), ctypes.sizeof(a)))

from pprint import pprint
import ctypes
 
class StructureTest(ctypes.Structure):
    _fields_ = [
        ('valA', ctypes.c_int),
        ('valB', ctypes.c_char * 20),
        ('valC', ctypes.c_char * 20),
        ('valD', ctypes.c_uint)
        ] 
 
# create ctype structure
a  = StructureTest()
a.valA = 1
a.valB = '1234'
a.valC = 'abcd'
a.valD = 1
 
# copy data to string
# or get a pointer to the structure
bytes = buffer(a)[:]
 
# modify data
a.valA = 0
a.valB = ''
a.valC = ''
a.valD = 0
 
# check modified data
print a.valA
print a.valB
print a.valC
print a.valD
 
# copy string data to ctype structure
ctypes.memmove(ctypes.addressof(a), bytes, min(len(bytes), ctypes.sizeof(a)))
 
# check data
print a.valA
print a.valB
print a.valC
print a.valD