How to customize Python ctypes 'c_wchar_p' and 'c_char_p' restype?

ctypes, python, python-3.x

Solution

You can subclass `c_char_p` to decode the UTF-8 string using the `_check_retval_` hook. For example:

import ctypes

class c_utf8_p(ctypes.c_char_p):  
    @classmethod      
    def _check_retval_(cls, result):
        value = result.value
        return value.decode('utf-8')

For example:

>>> PyUnicode_AsUTF8 = ctypes.pythonapi.PyUnicode_AsUTF8
>>> PyUnicode_AsUTF8.argtypes = [ctypes.py_object]
>>> PyUnicode_AsUTF8.restype = c_utf8_p
>>> PyUnicode_AsUTF8('\u0201')
'ȁ'

This won't work for a field in a `Structure`, but since it's a class, you can use a property or custom descriptor to encode and decode the bytes.

Problem

In Python 3 ``` function_name.restype = c_char_p # returns bytes ``` I have many such functions and for every one I need to do `str(ret, 'utf8')`. How can I create a `custom_c_char_p` that does this automatically to be declared like this? ``` function_name.restype = custom_c_char_p # should return str ``` C library also outputs UTF-16 as `c_wchar_p` which comes through as `str` to python, but when I do `ret.encode('utf16')`, I get `UnicodeDecodeError`. How do I customize `c_wchar_p` to ensure Python knows it's converting UTF-16 to get a proper `str` back?

Original source