File: ctypesutil.py

package info (click to toggle)
python-can 1.5.2-3
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 644 kB
  • ctags: 1,184
  • sloc: python: 4,373; makefile: 14
file content (92 lines) | stat: -rw-r--r-- 2,734 bytes parent folder | download
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
# -*- coding: utf-8 -*-

" Common ctypes utils "

import binascii
import ctypes
import logging
import sys

log = logging.getLogger('can.ctypesutil')

__all__ = ['CLibrary', 'HANDLE', 'PHANDLE']


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


try:
    _LibBase = ctypes.WinDLL
except AttributeError:
    _LibBase = ctypes.CDLL

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
else:
    CLibrary = CLibrary_Unix


# Common win32 definitions
class HANDLE(ctypes.c_void_p):
    pass

PHANDLE = ctypes.POINTER(HANDLE)