简体   繁体   中英

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

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM