#------------------- wrap C/Fortran routines -------------------# import numpy as np from ctypes import * class Struct: pass # converts numpy array to void * for calling C/Fortran routines def loc(array): return array.ctypes.data_as(c_void_p) # defines converter functions depending on type of Python argument def noop(x): return x py2c = { np.ndarray:loc, np.float64:c_double, float:c_double, int:c_int, c_void_p:noop, str:noop, c_int:noop } class Wrap: def __init__(self, fun, check_args, argtypes): fun.restype=None if check_args: fun.argtypes=argtypes self.fun=fun self.convert=None def __call__(self, *args): if self.convert is None: self.convert=[ py2c[type(arg)] for arg in args] args = [ conv(arg) for conv,arg in zip(self.convert,args) ] return self.fun(*args) def typelist(argtypes): lst=[] for x in argtypes: if type(x) is int: lst+=(x-1)*[prev] # x-1 because prev has already been appended once else: lst.append(x) prev=x return lst class SharedLib: def __init__(self,vardict,name,check_args=True, prefix_so='',prefix_py=''): self.vardict, self.check_args = vardict, check_args self.prefix_so, self.prefix_py = prefix_so, prefix_py self.lib=cdll.LoadLibrary(name) self.vars={} def import_funs(self,prototypes,prefix=''): for proto in prototypes: names=[] while type(proto[0]) is str: names.append(proto.pop(0)) if proto[0] is None: proto=None else: proto = typelist(proto) for name in names: name = prefix+name soname = self.prefix_so+name print 'wrap.Sharedlib : importing', soname self.vardict[self.prefix_py+name] = Wrap(self.lib[soname], self.check_args, proto) def addvars(self,*types_and_names): for x in types_and_names: if type(x) is str: self.vars[x]=ctype.in_dll(self.lib, x.lower()) else: ctype = x def getvar(self,name): return self.vars[name].value def getvars(self,*names): return [self.vars[name].value for name in names] def setvar(self,name,val): self.vars[name].value=val def setvars(self,names,vals): for name,val in zip(names,vals): self.vars[name].value=val