[Tutor] How to wrap ctype functions

Mark Tolonen metolone+gmane at gmail.com
Fri Mar 5 09:05:58 CET 2010


"Jan Jansen" <knacktus at googlemail.com> wrote in message 
news:f17500b71003030943w606925edie41b41d6d64ef6cf at mail.gmail.com...
> Hi there,
>
> I wonder what's the best way to wrap given function calls (in this case
> ctype function calls but more generally built-in functions and those 
> kinds).
> I have a huge c library and almost all functions return an error code. The
> library also contains a function, that returns the corresponding error
> message to the error code. So, what I need to do for every call to one of
> the libraries functions looks like this:
>
> error_code = my_c_library.SOME_FUNCTION_
> CALL(argument)
> if error_code != 0:
>   error_message = my_c_library.GET_ERROR_TEXT(error_code)
>   print "error in function call SOME_FUNCTION_CALL"
>   print error_message
>   my_c_library.EXIT_AND_CLEAN_UP()

ctypes has a couple of methods to post process return values.

1.  A callable can be assigned has the .restype attribute of the function 
object.  In this case, the function is assumed to return an integer, and it 
is passed to the callable.  The function could raise an exception for 
non-zero return values.  This usage is deprecated.  See "16.15.1.8. Return 
types" in the Python docs (http://docs.python.org/library/ctypes.html).

2.  Any return type can be assigned to .restype, and a callable can be 
assigned to the .errcheck attribute.  This has more flexibility than #1 
since it works for return types without int.  The callable is provided the 
return value, original function object, and original arguments to help 
customize the behavior of the return value.  See "16.15.2.3. Foreign 
functions" in the docs.

>
> Also, for some function calls I would need to do some preperations like:
>
> error_code = my_c_library.LOG_IN_AS_ADMINISTRATOR(admin_user,
> admin_password)
> error_code = my_c_library.SOME_FUNCTION_CALL(argument)
>
> I like the decorator idea, but I can't figure out if it's applicable here.
> To be able to call the function in a manner like this would be great, e.g.
>
> @change_user(admin_user, admin_password)
> @error_handling
> my_c_library.SOME_FUNCTION_CALL(argument)

Decorators don't decorate calls to functions, just function declarations. 
Here's a *rough* example:

>>> def prep(func):
...   def prepwork(*args,**kwargs):
...      print 'doing prep work...'
...      func(*args,**kwargs)
...   return prepwork
...
>>> @prep
... def something(a,b):
...   print a,b
...
>>> something(1,2)
doing prep work...
1 2

-Mark




More information about the Tutor mailing list