1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
|
# coding: utf-8
"""
This module contains common `ctypes` utils.
"""
import binascii
import ctypes
import logging
import sys
log = logging.getLogger('can.ctypesutil')
__all__ = ['CLibrary', 'HANDLE', 'PHANDLE', 'HRESULT']
try:
_LibBase = ctypes.WinDLL
except AttributeError:
_LibBase = ctypes.CDLL
class LibraryMixin:
def map_symbol(self, func_name, restype=None, argtypes=(), errcheck=None):
"""
Map and return a symbol (function) from a C library. A reference to the
mapped symbol is also held in the instance
:param str func_name:
symbol_name
:param ctypes.c_* restype:
function result type (i.e. ctypes.c_ulong...), defaults to void
:param tuple(ctypes.c_* ... ) argtypes:
argument types, defaults to no args
:param callable errcheck:
optional error checking function, see ctypes docs for _FuncPtr
"""
if (argtypes):
prototype = self.function_type(restype, *argtypes)
else:
prototype = self.function_type(restype)
try:
symbol = prototype((func_name, self))
except AttributeError:
raise ImportError("Could not map function '{}' from library {}".format(func_name, self._name))
setattr(symbol, "_name", func_name)
log.debug('Wrapped function "{}", result type: {}, error_check {}'.format(func_name, type(restype), errcheck))
if (errcheck):
symbol.errcheck = errcheck
setattr(self, func_name, symbol)
return symbol
class CLibrary_Win32(_LibBase, LibraryMixin):
" Basic ctypes.WinDLL derived class + LibraryMixin "
def __init__(self, library_or_path):
if (isinstance(library_or_path, str)):
super(CLibrary_Win32, self).__init__(library_or_path)
else:
super(CLibrary_Win32, self).__init__(library_or_path._name, library_or_path._handle)
@property
def function_type(self):
return ctypes.WINFUNCTYPE
class CLibrary_Unix(ctypes.CDLL, LibraryMixin):
" Basic ctypes.CDLL derived class + LibraryMixin "
def __init__(self, library_or_path):
if (isinstance(library_or_path, str)):
super(CLibrary_Unix, self).__init__(library_or_path)
else:
super(CLibrary_Unix, self).__init__(library_or_path._name, library_or_path._handle)
@property
def function_type(self):
return ctypes.CFUNCTYPE
if sys.platform == "win32":
CLibrary = CLibrary_Win32
HRESULT = ctypes.HRESULT
else:
CLibrary = CLibrary_Unix
if sys.platform == "cygwin":
# Define HRESULT for cygwin
class HRESULT(ctypes.c_long):
pass
# Common win32 definitions
class HANDLE(ctypes.c_void_p):
pass
PHANDLE = ctypes.POINTER(HANDLE)
|