Eryk Sun <eryk...@gmail.com> added the comment:
Your example uses POINTER(c_double), not c_void_p. There's no problem with an actual pointer object (i.e. subclass of ctypes._Pointer). The problem is with simple types (i.e. immediate subclasses of ctypes._SimpleCData), including simple pointer types (i.e. c_void_p, c_char_p, c_wchar_p). Simple types are automatically converted to equivalent Python types when returned from functions or accessed in aggregates (i.e. structs and arrays). This is generally convenient, but at times it's a serious problem. Note that I said this is the case only for immediate subclasses of _SimpleCData. We can work around the behavior by using a subclass of the given simple type. For example: class my_wchar_p(ctypes.c_wchar_p): pass class T(ctypes.Structure): _fields_ = (('s1', ctypes.c_wchar_p), ('s2', my_wchar_p)) >>> t = T('abc', 'def') >>> t.s1 'abc' >>> t.s2 my_wchar_p(140497806976112) >>> t.s2.value 'def' If desired, we can retain the automatic conversion for function results by defining a staticmethod or classmethod named "_check_retval_" on the subclass. This method takes the result as parameter to be checked, possibly converted, and returned. One exception is that [wide-]character arrays always get converted into bytes/strings when accessed as fields of a struct. This is implemented in PyCField_FromDesc in Modules/_ctypes/cfield.c. We can't easily work around this hack because it doesn't check whether the base type is an immediate subclass of _SimpleCData. Instead we have to use the undocumented `offset` attribute. We can hide this workaround with a private field and a property. For example: class T(ctypes.Structure): _fields_ = (('s1', ctypes.c_wchar * 10), ('_s2', ctypes.c_wchar * 10)) @property def s2(self): offset = type(self)._s2.offset return (ctypes.c_wchar * 10).from_buffer(self, offset) >>> t = T('abc', 'def') >>> t._s2 'def' >>> t.s2 <__main__.c_wchar_Array_10 object at 0x7fc82c3a6510> >>> t.s2.value 'def' ---------- nosy: +eryksun _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue35390> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com