Source code for pyhesaff.ctypes_interface

from __future__ import absolute_import, division, print_function
from os.path import join, exists, dirname, normpath
import sys
import os
import ctypes as C


#============================
# general ctypes interface
#============================

__DEBUG_CLIB__ = '--debug' in sys.argv or '--debug-clib' in sys.argv


[docs]def get_lib_fname_list(libname): """ input <libname>: library name (e.g. 'hesaff', not 'libhesaff') returns <libnames>: list of plausible library file names """ if sys.platform.startswith('win32'): libnames = ['lib' + libname + '.dll', libname + '.dll'] elif sys.platform.startswith('darwin'): libnames = ['lib' + libname + '.dylib'] elif sys.platform.startswith('linux'): libnames = ['lib' + libname + '.so'] else: raise Exception('Unknown operating system: %s' % sys.platform) return libnames
[docs]def get_lib_dpath_list(root_dir): """ input <root_dir>: deepest directory to look for a library (dll, so, dylib) returns <libnames>: list of plausible directories to look. """ 'returns possible lib locations' get_lib_dpath_list = [root_dir, join(root_dir, 'lib'), join(root_dir, 'build'), join(root_dir, 'build', 'lib')] return get_lib_dpath_list
[docs]def find_lib_fpath(libname, root_dir, recurse_down=True, verbose=False): """ Search for the library """ lib_fname_list = get_lib_fname_list(libname) tried_fpaths = [] while root_dir is not None: for lib_fname in lib_fname_list: for lib_dpath in get_lib_dpath_list(root_dir): lib_fpath = normpath(join(lib_dpath, lib_fname)) if exists(lib_fpath): if verbose: print('\n[c] Checked: '.join(tried_fpaths)) if __DEBUG_CLIB__: print('using: %r' % lib_fpath) return lib_fpath else: # Remember which candiate library fpaths did not exist tried_fpaths.append(lib_fpath) _new_root = dirname(root_dir) if _new_root == root_dir: root_dir = None break else: root_dir = _new_root if not recurse_down: break msg = ('\n[C!] load_clib(libname=%r root_dir=%r, recurse_down=%r, verbose=%r)' % (libname, root_dir, recurse_down, verbose) + '\n[c!] Cannot FIND dynamic library') print(msg) print('\n[c!] Checked: '.join(tried_fpaths)) raise ImportError(msg)
[docs]def load_clib(libname, root_dir): """ Does the work. Args: libname: library name (e.g. 'hesaff', not 'libhesaff') root_dir: the deepest directory searched for the library file (dll, dylib, or so). Returns: clib: a ctypes object used to interface with the library """ lib_fpath = find_lib_fpath(libname, root_dir) try: clib = C.cdll[lib_fpath] def def_cfunc(return_type, func_name, arg_type_list): 'Function to define the types that python needs to talk to c' cfunc = getattr(clib, func_name) cfunc.restype = return_type cfunc.argtypes = arg_type_list clib.__LIB_FPATH__ = lib_fpath return clib, def_cfunc, lib_fpath except OSError as ex: print('[C!] Caught OSError:\n%s' % ex) errsuffix = 'Is there a missing dependency?' except Exception as ex: print('[C!] Caught Exception:\n%s' % ex) errsuffix = 'Was the library correctly compiled?' print('[C!] cwd=%r' % os.getcwd()) print('[C!] load_clib(libname=%r root_dir=%r)' % (libname, root_dir)) print('[C!] lib_fpath = %r' % lib_fpath) errmsg = '[C] Cannot LOAD %r dynamic library. ' % (libname,) + errsuffix print(errmsg) raise ImportError(errmsg)