14.14.1.8 Return types

###
14.14.1.8 Return types

By default functions are assumed to return the C `int` type. Other return types can be specified by setting the `restype` attribute of the function object.

Here is a more advanced example, it uses the `strchr` function, which expects a string pointer and a char, and returns a pointer to a string:

    >>> strchr = libc.strchr
    >>> strchr("abcdef", ord("d")) # doctest: +SKIP
    8059983
    >>> strchr.restype = c_char_p # c_char_p is a pointer to a string
    >>> strchr("abcdef", ord("d"))
    'def'
    >>> print strchr("abcdef", ord("x"))
    None
    >>>

If you want to avoid the `ord("x")` calls above, you can set the `argtypes` attribute, and the second argument will be converted from a single character Python string into a C char:

    >>> strchr.restype = c_char_p
    >>> strchr.argtypes = [c_char_p, c_char]
    >>> strchr("abcdef", "d")
    'def'
    >>> strchr("abcdef", "def")
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    ArgumentError: argument 2: exceptions.TypeError: one character string expected
    >>> print strchr("abcdef", "x")
    None
    >>> strchr("abcdef", "d")
    'def'
    >>>

You can also use a callable Python object (a function or a class for example) as the `restype` attribute, if the foreign function returns an integer. The callable will be called with the `integer` the C function returns, and the result of this call will be used as the result of your function call. This is useful to check for error return values and automatically raise an exception:

    >>> GetModuleHandle = windll.kernel32.GetModuleHandleA # doctest: +WINDOWS
    >>> def ValidHandle(value):
    ...     if value == 0:
    ...         raise WinError()
    ...     return value
    ...
    >>>
    >>> GetModuleHandle.restype = ValidHandle # doctest: +WINDOWS
    >>> GetModuleHandle(None) # doctest: +WINDOWS
    486539264
    >>> GetModuleHandle("something silly") # doctest: +WINDOWS
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
      File "<stdin>", line 3, in ValidHandle
    WindowsError: [Errno 126] The specified module could not be found.
    >>>

`WinError` is a function which will call Windows `FormatMessage()` api to get the string representation of an error code, and returns an exception. `WinError` takes an optional error code parameter, if no one is used, it calls `GetLastError()` to retrieve it.

Please note that a much more powerful error checking mechanism is available through the `errcheck` attribute; see the reference manual for details.