Distinguish between “fundamental” ctypes data types and subclasses thereof?
我正在使用一个代码生成器,它将围绕
1 2 3 4 5 6 | func = getattr(dll, 'UglyLongAndUselessCName') func.argtypes = [ctypes.c_uint32, ctypes.c_int8, ctypes.c_char_p] func.restype = ctypes.c_int16 def nice_python_name(handle: int, arg1: int, arg2: str) -> int: return func(handle, arg1, arg2) |
请注意python类型注释如何与函数参数的
接近问题
但是,文档还说,对于"基本数据类型的子类",此技巧将不起作用,调用加载的DLL函数将需要
这是
Fundamental data types, when returned as foreign function call results, or, for example, by retrieving structure field members or array items, are transparently converted to native Python types. In other words, if a foreign function has a
restype ofc_char_p , you will always receive a Python bytes object, not ac_char_p instance.Subclasses of fundamental data types do not inherit this behavior. So, if a foreign functions
restype is a subclass ofc_void_p , you will receive an instance of this subclass from the function call. Of course, you can get the value of the pointer by accessing the value attribute.
所以,我想解决这个问题。
似乎我需要知道类型是"基本"还是"子类"。这将帮助我定义代码的生成方式,即,对于"基本"类型,所生成的代码将类似于上述示例,对于"基本"类型的子类,它将具有从
题:
如何区分"基本
我查看了
另外,我是否会误解为这个问题也适用于输入参数,还是这仅适用于返回值?
... do I misunderstand it that this problem also applies to the input arguments, or is this only the deal for the returned values?
它不适用于输入参数,如以下序列所示:
1 2 3 4 5 6 7 8 9 10 | >>> dll=CDLL('msvcrt') >>> dll.printf.argtypes = c_char_p, >>> dll.printf(b'abc') # Note: 3 is the return value of printf abc3 >>> class LPCSTR(c_char_p): # define a subtype ... pass ... >>> dll.printf.argtypes = LPCSTR, >>> dll.printf(b'abc') abc3 |
转换对于输入子类型仍然有效; 但是,输出子类型的工作方式与您提到的文档引号不同:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> dll.ctime.argtypes = c_void_p, >>> dll.ctime.restype = c_char_p >>> dll.ctime(byref(c_int(5))) b'Wed Dec 31 16:00:05 1969 ' >>> dll.ctime.restype = LPCSTR >>> dll.ctime(byref(c_int(5))) # not converted to Python byte string LPCSTR(1989707373328) >>> x = dll.ctime(byref(c_int(5))) # but can get the value >>> x.value b'Wed Dec 31 16:00:05 1969 ' |