Source code for pylablib.aux_libs.devices.misc

from ...core.utils import files

import platform
import ctypes
import sys
import os.path
import os


[docs]def get_default_lib_folder(absolute=True): """ Get default DLL folder withing the package, depending on the Python bitness If ``absolute==True``, get absolute path (including pyLabLib folder); otherwise, get subfolder within pyLabLib folder. """ arch=platform.architecture()[0] if arch=="32bit": archfolder="x32" elif arch=="64bit": archfolder="x64" else: raise ImportError("Unexpected system architecture: {0}".format(arch)) module_folder=os.path.split(files.normalize_path(sys.modules[__name__].__file__))[0] if absolute else os.path.join("aux_libs","devices") return os.path.join(module_folder,"libs",archfolder)
default_lib_folder=get_default_lib_folder() default_rel_lib_folder=get_default_lib_folder(absolute=False)
[docs]def get_os_lib_folder(): """Get default Windows DLL folder (``System32`` or ``SysWOW64``, depending on Python and Windows bitness)""" if sys.platform!="win32": return "" arch=platform.architecture()[0] winarch="64bit" if platform.machine().endswith("64") else "32bit" if winarch==arch: return os.path.join(os.environ["WINDIR"],"System32") else: return os.path.join(os.environ["WINDIR"],"SysWOW64")
default_placing_message="The libraries should be placed in {} or in {}".format(default_lib_folder,get_os_lib_folder())
[docs]def load_lib(name, locations=("global",), call_conv="cdecl", locally=False, error_message=None, check_order="location"): """ Load DLL. Args: name: name or path of the library (can also be a list or a tuple with several names, which are tried in that order). locations: list or tuple of locations to search for a library; the function tries locations in order and returns the first successfully loaded library a location is a string which can be a path to the containing folder, ``"local"`` (local package path given by :func:`get_default_lib_folder`), or ``"global"`` (load path as is; also searches in the standard OS specified locations determined by ``PATH`` variable, e.g., ``System32`` folder) locally(bool): if ``True``, change local path to allow loading of dependent DLLs call_conv(str): DLL call convention; can be either ``"cdecl"`` (corresponds to ``ctypes.cdll``) or ``"stdcall"`` (corresponds to ``ctypes.windll``) error_message(str): error message to add in addition to the default error message shown when the DLL is not found check_order(str): determines the order in which possible combinations of names and locations are looped over; can be ``"location"`` (loop over locations, and for each location loop over names), ``"name"`` (loop over names, and for each name loop over locations), or a list of tuples ``[(loc,name)]`` specifying order of checking (in the latter case, `name` and `location` arguments are ignored, except for generating error mesage). """ if platform.system()!="Windows": raise OSError("DLLs are not available on non-Windows platform") if not isinstance(name,(list,tuple)): name=[name] if check_order=="location": check_order=[(loc,n) for loc in locations for n in name] elif check_order=="name": check_order=[(loc,n) for n in name for loc in locations] for loc,n in check_order: if loc=="local": folder=default_lib_folder elif loc=="global": folder="" else: if loc.lower().endswith(".dll"): folder,n=os.path.split(loc) else: folder=loc path=os.path.join(folder,n) if locally: loc_folder,loc_name=os.path.split(path) old_env_path=os.environ["PATH"] env_paths=old_env_path.split(";") if not any([files.paths_equal(loc_folder,ep) for ep in env_paths if ep]): os.environ["PATH"]=files.normalize_path(loc_folder)+";"+os.environ["PATH"]+";"+files.normalize_path(loc_folder)+";" path=loc_name try: if call_conv=="cdecl": return ctypes.cdll.LoadLibrary(path) elif call_conv=="stdcall": return ctypes.windll.LoadLibrary(path) else: raise ValueError("unrecognized call convention: {}".format(call_conv)) except OSError: if locally: os.environ["PATH"]=old_env_path error_message="\n"+error_message if error_message else "" raise OSError("can't import module {}".format(" or ".join(name))+error_message)