1 | n/a | """create and manipulate C data types in Python""" |
---|
2 | n/a | |
---|
3 | n/a | import os as _os, sys as _sys |
---|
4 | n/a | |
---|
5 | n/a | __version__ = "1.1.0" |
---|
6 | n/a | |
---|
7 | n/a | from _ctypes import Union, Structure, Array |
---|
8 | n/a | from _ctypes import _Pointer |
---|
9 | n/a | from _ctypes import CFuncPtr as _CFuncPtr |
---|
10 | n/a | from _ctypes import __version__ as _ctypes_version |
---|
11 | n/a | from _ctypes import RTLD_LOCAL, RTLD_GLOBAL |
---|
12 | n/a | from _ctypes import ArgumentError |
---|
13 | n/a | |
---|
14 | n/a | from struct import calcsize as _calcsize |
---|
15 | n/a | |
---|
16 | n/a | if __version__ != _ctypes_version: |
---|
17 | n/a | raise Exception("Version number mismatch", __version__, _ctypes_version) |
---|
18 | n/a | |
---|
19 | n/a | if _os.name == "nt": |
---|
20 | n/a | from _ctypes import FormatError |
---|
21 | n/a | |
---|
22 | n/a | DEFAULT_MODE = RTLD_LOCAL |
---|
23 | n/a | if _os.name == "posix" and _sys.platform == "darwin": |
---|
24 | n/a | # On OS X 10.3, we use RTLD_GLOBAL as default mode |
---|
25 | n/a | # because RTLD_LOCAL does not work at least on some |
---|
26 | n/a | # libraries. OS X 10.3 is Darwin 7, so we check for |
---|
27 | n/a | # that. |
---|
28 | n/a | |
---|
29 | n/a | if int(_os.uname().release.split('.')[0]) < 8: |
---|
30 | n/a | DEFAULT_MODE = RTLD_GLOBAL |
---|
31 | n/a | |
---|
32 | n/a | from _ctypes import FUNCFLAG_CDECL as _FUNCFLAG_CDECL, \ |
---|
33 | n/a | FUNCFLAG_PYTHONAPI as _FUNCFLAG_PYTHONAPI, \ |
---|
34 | n/a | FUNCFLAG_USE_ERRNO as _FUNCFLAG_USE_ERRNO, \ |
---|
35 | n/a | FUNCFLAG_USE_LASTERROR as _FUNCFLAG_USE_LASTERROR |
---|
36 | n/a | |
---|
37 | n/a | # WINOLEAPI -> HRESULT |
---|
38 | n/a | # WINOLEAPI_(type) |
---|
39 | n/a | # |
---|
40 | n/a | # STDMETHODCALLTYPE |
---|
41 | n/a | # |
---|
42 | n/a | # STDMETHOD(name) |
---|
43 | n/a | # STDMETHOD_(type, name) |
---|
44 | n/a | # |
---|
45 | n/a | # STDAPICALLTYPE |
---|
46 | n/a | |
---|
47 | n/a | def create_string_buffer(init, size=None): |
---|
48 | n/a | """create_string_buffer(aBytes) -> character array |
---|
49 | n/a | create_string_buffer(anInteger) -> character array |
---|
50 | n/a | create_string_buffer(aBytes, anInteger) -> character array |
---|
51 | n/a | """ |
---|
52 | n/a | if isinstance(init, bytes): |
---|
53 | n/a | if size is None: |
---|
54 | n/a | size = len(init)+1 |
---|
55 | n/a | buftype = c_char * size |
---|
56 | n/a | buf = buftype() |
---|
57 | n/a | buf.value = init |
---|
58 | n/a | return buf |
---|
59 | n/a | elif isinstance(init, int): |
---|
60 | n/a | buftype = c_char * init |
---|
61 | n/a | buf = buftype() |
---|
62 | n/a | return buf |
---|
63 | n/a | raise TypeError(init) |
---|
64 | n/a | |
---|
65 | n/a | def c_buffer(init, size=None): |
---|
66 | n/a | ## "deprecated, use create_string_buffer instead" |
---|
67 | n/a | ## import warnings |
---|
68 | n/a | ## warnings.warn("c_buffer is deprecated, use create_string_buffer instead", |
---|
69 | n/a | ## DeprecationWarning, stacklevel=2) |
---|
70 | n/a | return create_string_buffer(init, size) |
---|
71 | n/a | |
---|
72 | n/a | _c_functype_cache = {} |
---|
73 | n/a | def CFUNCTYPE(restype, *argtypes, **kw): |
---|
74 | n/a | """CFUNCTYPE(restype, *argtypes, |
---|
75 | n/a | use_errno=False, use_last_error=False) -> function prototype. |
---|
76 | n/a | |
---|
77 | n/a | restype: the result type |
---|
78 | n/a | argtypes: a sequence specifying the argument types |
---|
79 | n/a | |
---|
80 | n/a | The function prototype can be called in different ways to create a |
---|
81 | n/a | callable object: |
---|
82 | n/a | |
---|
83 | n/a | prototype(integer address) -> foreign function |
---|
84 | n/a | prototype(callable) -> create and return a C callable function from callable |
---|
85 | n/a | prototype(integer index, method name[, paramflags]) -> foreign function calling a COM method |
---|
86 | n/a | prototype((ordinal number, dll object)[, paramflags]) -> foreign function exported by ordinal |
---|
87 | n/a | prototype((function name, dll object)[, paramflags]) -> foreign function exported by name |
---|
88 | n/a | """ |
---|
89 | n/a | flags = _FUNCFLAG_CDECL |
---|
90 | n/a | if kw.pop("use_errno", False): |
---|
91 | n/a | flags |= _FUNCFLAG_USE_ERRNO |
---|
92 | n/a | if kw.pop("use_last_error", False): |
---|
93 | n/a | flags |= _FUNCFLAG_USE_LASTERROR |
---|
94 | n/a | if kw: |
---|
95 | n/a | raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) |
---|
96 | n/a | try: |
---|
97 | n/a | return _c_functype_cache[(restype, argtypes, flags)] |
---|
98 | n/a | except KeyError: |
---|
99 | n/a | class CFunctionType(_CFuncPtr): |
---|
100 | n/a | _argtypes_ = argtypes |
---|
101 | n/a | _restype_ = restype |
---|
102 | n/a | _flags_ = flags |
---|
103 | n/a | _c_functype_cache[(restype, argtypes, flags)] = CFunctionType |
---|
104 | n/a | return CFunctionType |
---|
105 | n/a | |
---|
106 | n/a | if _os.name == "nt": |
---|
107 | n/a | from _ctypes import LoadLibrary as _dlopen |
---|
108 | n/a | from _ctypes import FUNCFLAG_STDCALL as _FUNCFLAG_STDCALL |
---|
109 | n/a | |
---|
110 | n/a | _win_functype_cache = {} |
---|
111 | n/a | def WINFUNCTYPE(restype, *argtypes, **kw): |
---|
112 | n/a | # docstring set later (very similar to CFUNCTYPE.__doc__) |
---|
113 | n/a | flags = _FUNCFLAG_STDCALL |
---|
114 | n/a | if kw.pop("use_errno", False): |
---|
115 | n/a | flags |= _FUNCFLAG_USE_ERRNO |
---|
116 | n/a | if kw.pop("use_last_error", False): |
---|
117 | n/a | flags |= _FUNCFLAG_USE_LASTERROR |
---|
118 | n/a | if kw: |
---|
119 | n/a | raise ValueError("unexpected keyword argument(s) %s" % kw.keys()) |
---|
120 | n/a | try: |
---|
121 | n/a | return _win_functype_cache[(restype, argtypes, flags)] |
---|
122 | n/a | except KeyError: |
---|
123 | n/a | class WinFunctionType(_CFuncPtr): |
---|
124 | n/a | _argtypes_ = argtypes |
---|
125 | n/a | _restype_ = restype |
---|
126 | n/a | _flags_ = flags |
---|
127 | n/a | _win_functype_cache[(restype, argtypes, flags)] = WinFunctionType |
---|
128 | n/a | return WinFunctionType |
---|
129 | n/a | if WINFUNCTYPE.__doc__: |
---|
130 | n/a | WINFUNCTYPE.__doc__ = CFUNCTYPE.__doc__.replace("CFUNCTYPE", "WINFUNCTYPE") |
---|
131 | n/a | |
---|
132 | n/a | elif _os.name == "posix": |
---|
133 | n/a | from _ctypes import dlopen as _dlopen |
---|
134 | n/a | |
---|
135 | n/a | from _ctypes import sizeof, byref, addressof, alignment, resize |
---|
136 | n/a | from _ctypes import get_errno, set_errno |
---|
137 | n/a | from _ctypes import _SimpleCData |
---|
138 | n/a | |
---|
139 | n/a | def _check_size(typ, typecode=None): |
---|
140 | n/a | # Check if sizeof(ctypes_type) against struct.calcsize. This |
---|
141 | n/a | # should protect somewhat against a misconfigured libffi. |
---|
142 | n/a | from struct import calcsize |
---|
143 | n/a | if typecode is None: |
---|
144 | n/a | # Most _type_ codes are the same as used in struct |
---|
145 | n/a | typecode = typ._type_ |
---|
146 | n/a | actual, required = sizeof(typ), calcsize(typecode) |
---|
147 | n/a | if actual != required: |
---|
148 | n/a | raise SystemError("sizeof(%s) wrong: %d instead of %d" % \ |
---|
149 | n/a | (typ, actual, required)) |
---|
150 | n/a | |
---|
151 | n/a | class py_object(_SimpleCData): |
---|
152 | n/a | _type_ = "O" |
---|
153 | n/a | def __repr__(self): |
---|
154 | n/a | try: |
---|
155 | n/a | return super().__repr__() |
---|
156 | n/a | except ValueError: |
---|
157 | n/a | return "%s(<NULL>)" % type(self).__name__ |
---|
158 | n/a | _check_size(py_object, "P") |
---|
159 | n/a | |
---|
160 | n/a | class c_short(_SimpleCData): |
---|
161 | n/a | _type_ = "h" |
---|
162 | n/a | _check_size(c_short) |
---|
163 | n/a | |
---|
164 | n/a | class c_ushort(_SimpleCData): |
---|
165 | n/a | _type_ = "H" |
---|
166 | n/a | _check_size(c_ushort) |
---|
167 | n/a | |
---|
168 | n/a | class c_long(_SimpleCData): |
---|
169 | n/a | _type_ = "l" |
---|
170 | n/a | _check_size(c_long) |
---|
171 | n/a | |
---|
172 | n/a | class c_ulong(_SimpleCData): |
---|
173 | n/a | _type_ = "L" |
---|
174 | n/a | _check_size(c_ulong) |
---|
175 | n/a | |
---|
176 | n/a | if _calcsize("i") == _calcsize("l"): |
---|
177 | n/a | # if int and long have the same size, make c_int an alias for c_long |
---|
178 | n/a | c_int = c_long |
---|
179 | n/a | c_uint = c_ulong |
---|
180 | n/a | else: |
---|
181 | n/a | class c_int(_SimpleCData): |
---|
182 | n/a | _type_ = "i" |
---|
183 | n/a | _check_size(c_int) |
---|
184 | n/a | |
---|
185 | n/a | class c_uint(_SimpleCData): |
---|
186 | n/a | _type_ = "I" |
---|
187 | n/a | _check_size(c_uint) |
---|
188 | n/a | |
---|
189 | n/a | class c_float(_SimpleCData): |
---|
190 | n/a | _type_ = "f" |
---|
191 | n/a | _check_size(c_float) |
---|
192 | n/a | |
---|
193 | n/a | class c_double(_SimpleCData): |
---|
194 | n/a | _type_ = "d" |
---|
195 | n/a | _check_size(c_double) |
---|
196 | n/a | |
---|
197 | n/a | class c_longdouble(_SimpleCData): |
---|
198 | n/a | _type_ = "g" |
---|
199 | n/a | if sizeof(c_longdouble) == sizeof(c_double): |
---|
200 | n/a | c_longdouble = c_double |
---|
201 | n/a | |
---|
202 | n/a | if _calcsize("l") == _calcsize("q"): |
---|
203 | n/a | # if long and long long have the same size, make c_longlong an alias for c_long |
---|
204 | n/a | c_longlong = c_long |
---|
205 | n/a | c_ulonglong = c_ulong |
---|
206 | n/a | else: |
---|
207 | n/a | class c_longlong(_SimpleCData): |
---|
208 | n/a | _type_ = "q" |
---|
209 | n/a | _check_size(c_longlong) |
---|
210 | n/a | |
---|
211 | n/a | class c_ulonglong(_SimpleCData): |
---|
212 | n/a | _type_ = "Q" |
---|
213 | n/a | ## def from_param(cls, val): |
---|
214 | n/a | ## return ('d', float(val), val) |
---|
215 | n/a | ## from_param = classmethod(from_param) |
---|
216 | n/a | _check_size(c_ulonglong) |
---|
217 | n/a | |
---|
218 | n/a | class c_ubyte(_SimpleCData): |
---|
219 | n/a | _type_ = "B" |
---|
220 | n/a | c_ubyte.__ctype_le__ = c_ubyte.__ctype_be__ = c_ubyte |
---|
221 | n/a | # backward compatibility: |
---|
222 | n/a | ##c_uchar = c_ubyte |
---|
223 | n/a | _check_size(c_ubyte) |
---|
224 | n/a | |
---|
225 | n/a | class c_byte(_SimpleCData): |
---|
226 | n/a | _type_ = "b" |
---|
227 | n/a | c_byte.__ctype_le__ = c_byte.__ctype_be__ = c_byte |
---|
228 | n/a | _check_size(c_byte) |
---|
229 | n/a | |
---|
230 | n/a | class c_char(_SimpleCData): |
---|
231 | n/a | _type_ = "c" |
---|
232 | n/a | c_char.__ctype_le__ = c_char.__ctype_be__ = c_char |
---|
233 | n/a | _check_size(c_char) |
---|
234 | n/a | |
---|
235 | n/a | class c_char_p(_SimpleCData): |
---|
236 | n/a | _type_ = "z" |
---|
237 | n/a | def __repr__(self): |
---|
238 | n/a | return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) |
---|
239 | n/a | _check_size(c_char_p, "P") |
---|
240 | n/a | |
---|
241 | n/a | class c_void_p(_SimpleCData): |
---|
242 | n/a | _type_ = "P" |
---|
243 | n/a | c_voidp = c_void_p # backwards compatibility (to a bug) |
---|
244 | n/a | _check_size(c_void_p) |
---|
245 | n/a | |
---|
246 | n/a | class c_bool(_SimpleCData): |
---|
247 | n/a | _type_ = "?" |
---|
248 | n/a | |
---|
249 | n/a | from _ctypes import POINTER, pointer, _pointer_type_cache |
---|
250 | n/a | |
---|
251 | n/a | class c_wchar_p(_SimpleCData): |
---|
252 | n/a | _type_ = "Z" |
---|
253 | n/a | def __repr__(self): |
---|
254 | n/a | return "%s(%s)" % (self.__class__.__name__, c_void_p.from_buffer(self).value) |
---|
255 | n/a | |
---|
256 | n/a | class c_wchar(_SimpleCData): |
---|
257 | n/a | _type_ = "u" |
---|
258 | n/a | |
---|
259 | n/a | def _reset_cache(): |
---|
260 | n/a | _pointer_type_cache.clear() |
---|
261 | n/a | _c_functype_cache.clear() |
---|
262 | n/a | if _os.name == "nt": |
---|
263 | n/a | _win_functype_cache.clear() |
---|
264 | n/a | # _SimpleCData.c_wchar_p_from_param |
---|
265 | n/a | POINTER(c_wchar).from_param = c_wchar_p.from_param |
---|
266 | n/a | # _SimpleCData.c_char_p_from_param |
---|
267 | n/a | POINTER(c_char).from_param = c_char_p.from_param |
---|
268 | n/a | _pointer_type_cache[None] = c_void_p |
---|
269 | n/a | # XXX for whatever reasons, creating the first instance of a callback |
---|
270 | n/a | # function is needed for the unittests on Win64 to succeed. This MAY |
---|
271 | n/a | # be a compiler bug, since the problem occurs only when _ctypes is |
---|
272 | n/a | # compiled with the MS SDK compiler. Or an uninitialized variable? |
---|
273 | n/a | CFUNCTYPE(c_int)(lambda: None) |
---|
274 | n/a | |
---|
275 | n/a | def create_unicode_buffer(init, size=None): |
---|
276 | n/a | """create_unicode_buffer(aString) -> character array |
---|
277 | n/a | create_unicode_buffer(anInteger) -> character array |
---|
278 | n/a | create_unicode_buffer(aString, anInteger) -> character array |
---|
279 | n/a | """ |
---|
280 | n/a | if isinstance(init, str): |
---|
281 | n/a | if size is None: |
---|
282 | n/a | size = len(init)+1 |
---|
283 | n/a | buftype = c_wchar * size |
---|
284 | n/a | buf = buftype() |
---|
285 | n/a | buf.value = init |
---|
286 | n/a | return buf |
---|
287 | n/a | elif isinstance(init, int): |
---|
288 | n/a | buftype = c_wchar * init |
---|
289 | n/a | buf = buftype() |
---|
290 | n/a | return buf |
---|
291 | n/a | raise TypeError(init) |
---|
292 | n/a | |
---|
293 | n/a | |
---|
294 | n/a | # XXX Deprecated |
---|
295 | n/a | def SetPointerType(pointer, cls): |
---|
296 | n/a | if _pointer_type_cache.get(cls, None) is not None: |
---|
297 | n/a | raise RuntimeError("This type already exists in the cache") |
---|
298 | n/a | if id(pointer) not in _pointer_type_cache: |
---|
299 | n/a | raise RuntimeError("What's this???") |
---|
300 | n/a | pointer.set_type(cls) |
---|
301 | n/a | _pointer_type_cache[cls] = pointer |
---|
302 | n/a | del _pointer_type_cache[id(pointer)] |
---|
303 | n/a | |
---|
304 | n/a | # XXX Deprecated |
---|
305 | n/a | def ARRAY(typ, len): |
---|
306 | n/a | return typ * len |
---|
307 | n/a | |
---|
308 | n/a | ################################################################ |
---|
309 | n/a | |
---|
310 | n/a | |
---|
311 | n/a | class CDLL(object): |
---|
312 | n/a | """An instance of this class represents a loaded dll/shared |
---|
313 | n/a | library, exporting functions using the standard C calling |
---|
314 | n/a | convention (named 'cdecl' on Windows). |
---|
315 | n/a | |
---|
316 | n/a | The exported functions can be accessed as attributes, or by |
---|
317 | n/a | indexing with the function name. Examples: |
---|
318 | n/a | |
---|
319 | n/a | <obj>.qsort -> callable object |
---|
320 | n/a | <obj>['qsort'] -> callable object |
---|
321 | n/a | |
---|
322 | n/a | Calling the functions releases the Python GIL during the call and |
---|
323 | n/a | reacquires it afterwards. |
---|
324 | n/a | """ |
---|
325 | n/a | _func_flags_ = _FUNCFLAG_CDECL |
---|
326 | n/a | _func_restype_ = c_int |
---|
327 | n/a | # default values for repr |
---|
328 | n/a | _name = '<uninitialized>' |
---|
329 | n/a | _handle = 0 |
---|
330 | n/a | _FuncPtr = None |
---|
331 | n/a | |
---|
332 | n/a | def __init__(self, name, mode=DEFAULT_MODE, handle=None, |
---|
333 | n/a | use_errno=False, |
---|
334 | n/a | use_last_error=False): |
---|
335 | n/a | self._name = name |
---|
336 | n/a | flags = self._func_flags_ |
---|
337 | n/a | if use_errno: |
---|
338 | n/a | flags |= _FUNCFLAG_USE_ERRNO |
---|
339 | n/a | if use_last_error: |
---|
340 | n/a | flags |= _FUNCFLAG_USE_LASTERROR |
---|
341 | n/a | |
---|
342 | n/a | class _FuncPtr(_CFuncPtr): |
---|
343 | n/a | _flags_ = flags |
---|
344 | n/a | _restype_ = self._func_restype_ |
---|
345 | n/a | self._FuncPtr = _FuncPtr |
---|
346 | n/a | |
---|
347 | n/a | if handle is None: |
---|
348 | n/a | self._handle = _dlopen(self._name, mode) |
---|
349 | n/a | else: |
---|
350 | n/a | self._handle = handle |
---|
351 | n/a | |
---|
352 | n/a | def __repr__(self): |
---|
353 | n/a | return "<%s '%s', handle %x at %#x>" % \ |
---|
354 | n/a | (self.__class__.__name__, self._name, |
---|
355 | n/a | (self._handle & (_sys.maxsize*2 + 1)), |
---|
356 | n/a | id(self) & (_sys.maxsize*2 + 1)) |
---|
357 | n/a | |
---|
358 | n/a | def __getattr__(self, name): |
---|
359 | n/a | if name.startswith('__') and name.endswith('__'): |
---|
360 | n/a | raise AttributeError(name) |
---|
361 | n/a | func = self.__getitem__(name) |
---|
362 | n/a | setattr(self, name, func) |
---|
363 | n/a | return func |
---|
364 | n/a | |
---|
365 | n/a | def __getitem__(self, name_or_ordinal): |
---|
366 | n/a | func = self._FuncPtr((name_or_ordinal, self)) |
---|
367 | n/a | if not isinstance(name_or_ordinal, int): |
---|
368 | n/a | func.__name__ = name_or_ordinal |
---|
369 | n/a | return func |
---|
370 | n/a | |
---|
371 | n/a | class PyDLL(CDLL): |
---|
372 | n/a | """This class represents the Python library itself. It allows |
---|
373 | n/a | accessing Python API functions. The GIL is not released, and |
---|
374 | n/a | Python exceptions are handled correctly. |
---|
375 | n/a | """ |
---|
376 | n/a | _func_flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI |
---|
377 | n/a | |
---|
378 | n/a | if _os.name == "nt": |
---|
379 | n/a | |
---|
380 | n/a | class WinDLL(CDLL): |
---|
381 | n/a | """This class represents a dll exporting functions using the |
---|
382 | n/a | Windows stdcall calling convention. |
---|
383 | n/a | """ |
---|
384 | n/a | _func_flags_ = _FUNCFLAG_STDCALL |
---|
385 | n/a | |
---|
386 | n/a | # XXX Hm, what about HRESULT as normal parameter? |
---|
387 | n/a | # Mustn't it derive from c_long then? |
---|
388 | n/a | from _ctypes import _check_HRESULT, _SimpleCData |
---|
389 | n/a | class HRESULT(_SimpleCData): |
---|
390 | n/a | _type_ = "l" |
---|
391 | n/a | # _check_retval_ is called with the function's result when it |
---|
392 | n/a | # is used as restype. It checks for the FAILED bit, and |
---|
393 | n/a | # raises an OSError if it is set. |
---|
394 | n/a | # |
---|
395 | n/a | # The _check_retval_ method is implemented in C, so that the |
---|
396 | n/a | # method definition itself is not included in the traceback |
---|
397 | n/a | # when it raises an error - that is what we want (and Python |
---|
398 | n/a | # doesn't have a way to raise an exception in the caller's |
---|
399 | n/a | # frame). |
---|
400 | n/a | _check_retval_ = _check_HRESULT |
---|
401 | n/a | |
---|
402 | n/a | class OleDLL(CDLL): |
---|
403 | n/a | """This class represents a dll exporting functions using the |
---|
404 | n/a | Windows stdcall calling convention, and returning HRESULT. |
---|
405 | n/a | HRESULT error values are automatically raised as OSError |
---|
406 | n/a | exceptions. |
---|
407 | n/a | """ |
---|
408 | n/a | _func_flags_ = _FUNCFLAG_STDCALL |
---|
409 | n/a | _func_restype_ = HRESULT |
---|
410 | n/a | |
---|
411 | n/a | class LibraryLoader(object): |
---|
412 | n/a | def __init__(self, dlltype): |
---|
413 | n/a | self._dlltype = dlltype |
---|
414 | n/a | |
---|
415 | n/a | def __getattr__(self, name): |
---|
416 | n/a | if name[0] == '_': |
---|
417 | n/a | raise AttributeError(name) |
---|
418 | n/a | dll = self._dlltype(name) |
---|
419 | n/a | setattr(self, name, dll) |
---|
420 | n/a | return dll |
---|
421 | n/a | |
---|
422 | n/a | def __getitem__(self, name): |
---|
423 | n/a | return getattr(self, name) |
---|
424 | n/a | |
---|
425 | n/a | def LoadLibrary(self, name): |
---|
426 | n/a | return self._dlltype(name) |
---|
427 | n/a | |
---|
428 | n/a | cdll = LibraryLoader(CDLL) |
---|
429 | n/a | pydll = LibraryLoader(PyDLL) |
---|
430 | n/a | |
---|
431 | n/a | if _os.name == "nt": |
---|
432 | n/a | pythonapi = PyDLL("python dll", None, _sys.dllhandle) |
---|
433 | n/a | elif _sys.platform == "cygwin": |
---|
434 | n/a | pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) |
---|
435 | n/a | else: |
---|
436 | n/a | pythonapi = PyDLL(None) |
---|
437 | n/a | |
---|
438 | n/a | |
---|
439 | n/a | if _os.name == "nt": |
---|
440 | n/a | windll = LibraryLoader(WinDLL) |
---|
441 | n/a | oledll = LibraryLoader(OleDLL) |
---|
442 | n/a | |
---|
443 | n/a | if _os.name == "nt": |
---|
444 | n/a | GetLastError = windll.kernel32.GetLastError |
---|
445 | n/a | else: |
---|
446 | n/a | GetLastError = windll.coredll.GetLastError |
---|
447 | n/a | from _ctypes import get_last_error, set_last_error |
---|
448 | n/a | |
---|
449 | n/a | def WinError(code=None, descr=None): |
---|
450 | n/a | if code is None: |
---|
451 | n/a | code = GetLastError() |
---|
452 | n/a | if descr is None: |
---|
453 | n/a | descr = FormatError(code).strip() |
---|
454 | n/a | return OSError(None, descr, None, code) |
---|
455 | n/a | |
---|
456 | n/a | if sizeof(c_uint) == sizeof(c_void_p): |
---|
457 | n/a | c_size_t = c_uint |
---|
458 | n/a | c_ssize_t = c_int |
---|
459 | n/a | elif sizeof(c_ulong) == sizeof(c_void_p): |
---|
460 | n/a | c_size_t = c_ulong |
---|
461 | n/a | c_ssize_t = c_long |
---|
462 | n/a | elif sizeof(c_ulonglong) == sizeof(c_void_p): |
---|
463 | n/a | c_size_t = c_ulonglong |
---|
464 | n/a | c_ssize_t = c_longlong |
---|
465 | n/a | |
---|
466 | n/a | # functions |
---|
467 | n/a | |
---|
468 | n/a | from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr |
---|
469 | n/a | |
---|
470 | n/a | ## void *memmove(void *, const void *, size_t); |
---|
471 | n/a | memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) |
---|
472 | n/a | |
---|
473 | n/a | ## void *memset(void *, int, size_t) |
---|
474 | n/a | memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) |
---|
475 | n/a | |
---|
476 | n/a | def PYFUNCTYPE(restype, *argtypes): |
---|
477 | n/a | class CFunctionType(_CFuncPtr): |
---|
478 | n/a | _argtypes_ = argtypes |
---|
479 | n/a | _restype_ = restype |
---|
480 | n/a | _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI |
---|
481 | n/a | return CFunctionType |
---|
482 | n/a | |
---|
483 | n/a | _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) |
---|
484 | n/a | def cast(obj, typ): |
---|
485 | n/a | return _cast(obj, obj, typ) |
---|
486 | n/a | |
---|
487 | n/a | _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) |
---|
488 | n/a | def string_at(ptr, size=-1): |
---|
489 | n/a | """string_at(addr[, size]) -> string |
---|
490 | n/a | |
---|
491 | n/a | Return the string at addr.""" |
---|
492 | n/a | return _string_at(ptr, size) |
---|
493 | n/a | |
---|
494 | n/a | try: |
---|
495 | n/a | from _ctypes import _wstring_at_addr |
---|
496 | n/a | except ImportError: |
---|
497 | n/a | pass |
---|
498 | n/a | else: |
---|
499 | n/a | _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) |
---|
500 | n/a | def wstring_at(ptr, size=-1): |
---|
501 | n/a | """wstring_at(addr[, size]) -> string |
---|
502 | n/a | |
---|
503 | n/a | Return the string at addr.""" |
---|
504 | n/a | return _wstring_at(ptr, size) |
---|
505 | n/a | |
---|
506 | n/a | |
---|
507 | n/a | if _os.name == "nt": # COM stuff |
---|
508 | n/a | def DllGetClassObject(rclsid, riid, ppv): |
---|
509 | n/a | try: |
---|
510 | n/a | ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) |
---|
511 | n/a | except ImportError: |
---|
512 | n/a | return -2147221231 # CLASS_E_CLASSNOTAVAILABLE |
---|
513 | n/a | else: |
---|
514 | n/a | return ccom.DllGetClassObject(rclsid, riid, ppv) |
---|
515 | n/a | |
---|
516 | n/a | def DllCanUnloadNow(): |
---|
517 | n/a | try: |
---|
518 | n/a | ccom = __import__("comtypes.server.inprocserver", globals(), locals(), ['*']) |
---|
519 | n/a | except ImportError: |
---|
520 | n/a | return 0 # S_OK |
---|
521 | n/a | return ccom.DllCanUnloadNow() |
---|
522 | n/a | |
---|
523 | n/a | from ctypes._endian import BigEndianStructure, LittleEndianStructure |
---|
524 | n/a | |
---|
525 | n/a | # Fill in specifically-sized types |
---|
526 | n/a | c_int8 = c_byte |
---|
527 | n/a | c_uint8 = c_ubyte |
---|
528 | n/a | for kind in [c_short, c_int, c_long, c_longlong]: |
---|
529 | n/a | if sizeof(kind) == 2: c_int16 = kind |
---|
530 | n/a | elif sizeof(kind) == 4: c_int32 = kind |
---|
531 | n/a | elif sizeof(kind) == 8: c_int64 = kind |
---|
532 | n/a | for kind in [c_ushort, c_uint, c_ulong, c_ulonglong]: |
---|
533 | n/a | if sizeof(kind) == 2: c_uint16 = kind |
---|
534 | n/a | elif sizeof(kind) == 4: c_uint32 = kind |
---|
535 | n/a | elif sizeof(kind) == 8: c_uint64 = kind |
---|
536 | n/a | del(kind) |
---|
537 | n/a | |
---|
538 | n/a | _reset_cache() |
---|