# # (C) Copyright 2015 Enthought, Inc., Austin, TX # All right reserved. # # This file is open source software distributed according to the terms in # LICENSE.txt # """ Utility functions to help with cffi wrapping. """ from __future__ import absolute_import from win32ctypes.core.compat import is_bytes, is_integer, text_type from cffi import FFI ffi = FFI() ffi.set_unicode(True) def HMODULE(cdata): return int(ffi.cast("intptr_t", cdata)) def PVOID(x): return ffi.cast("void *", x) def IS_INTRESOURCE(x): """ Check if x is an index into the id list. """ return int(ffi.cast("uintptr_t", x)) >> 16 == 0 def RESOURCE(resource): """ Convert a resource into a compatible input for cffi. """ if is_integer(resource): resource = ffi.cast('wchar_t *', resource) elif is_bytes(resource): resource = text_type(resource) return resource def resource(lpRESOURCEID): """ Convert the windows RESOURCE into a python friendly object. """ if IS_INTRESOURCE(lpRESOURCEID): resource = int(ffi.cast("uintptr_t", lpRESOURCEID)) else: resource = ffi.string(lpRESOURCEID) return resource class ErrorWhen(object): """ Callable factory for raising errors when calling cffi functions. """ def __init__(self, check, raise_on_zero=True): """ Constructor Parameters ---------- check : The return value that designates that an error has taken place. raise_on_zero : bool When set any error will be raised. When false the winerror is checked and only non-zero win errors are raised. Currently this parameters is used to workaround issues with the win32 implementation in ``wine``. """ self._check = check self._raise_on_zero = raise_on_zero def __call__(self, value, function_name=''): if value == self._check: self._raise_error(function_name) else: return value def _raise_error(self, function_name=''): code, message = ffi.getwinerror() exception = WindowsError() exception.errno = ffi.errno exception.winerror = code exception.strerror = message exception.function = function_name raise exception check_null = ErrorWhen(ffi.NULL) check_zero = ErrorWhen(0) check_false = ErrorWhen(False) class Libraries(object): def __getattr__(self, name): library = ffi.dlopen('{}.dll'.format(name)) self.__dict__[name] = library return library dlls = Libraries()