提问者:小点点

Python3. x ctypec_wchar_p和c_char_p返回状态不同于ctype文档


Python3.5.2

当我尝试使用ctype调用CDLL时,我注意到了这个问题,C函数类似于:

MEASURE_API int InitTester(char *ipAddress)

所以我需要从Python传递一个IP地址字符串(例如,192.168.100.100)到ctype,根据Python3.5的ctype文档,我尝试了c_wchar_p和c_char_p,但都不起作用,我从c dll端得到了错误代码retrun。我有一些其他函数调用这个dll传递c_int、c_void_p、c_bool和其他数据类型,这些都没问题。追溯发现c_wchar_p和c_char_p返回结果的行为与它应该基于ctype文档的行为不同。从3.5Python的ctype文档:

>>> c_wchar_p("Hello, World")
c_wchar_p('Hello, World')

它返回ctype字符串。但是我在控制台中执行相同cmdPython结果:

>>> from ctypes import *
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004842736)
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004841680)
>>> c_wchar_p("Hello, World")
c_wchar_p(1374004842736)

所以似乎原始字符串部分可能变成了内存地址。深入挖掘,发现它是否Python2. x(默认编码是ASCII),然后返回显示字符串,就像3.5 ctype文档显示的Python一样。但是在Python3.x(默认编码是UTF-8)中,它总是返回数字,行为与文档不同。在多台PC上检查。并且理解了这一部分,我们可以使用.value返回原始字符串。但是它不能传递给必须是ctype的C函数。

  • 有人能解释一下行为类型吗?
  • 以及如何解决这个问题,以便我可以获得与Python3.5中的ctype文档相同的行为,然后使调用c dll工作?

提前多谢了~


共1个答案

匿名用户

我现在非常确定,您应该使用create_string_buffer而不是c_char_p将字符串传递给您的C函数;非const签名表示突变,需要文档中所述的字符缓冲区:

但是,您应该小心,不要将它们传递给期望指向可变内存的指针的函数。如果您需要可变内存块,ctype有一个create_string_buffer()函数,它以各种方式创建这些块。可以使用原始属性访问(或更改)当前内存块的内容;如果您想以NUL终止字符串的形式访问它,请使用value属性。

(强调我的)

所以本质上,create_string_buffer(b'192.168.100.100')

除此之外,似乎留档确实可能是关闭的。__repr__forc_char_pc_wchar_p的实现返回它们的名称,并且在创建指向它们的内存缓冲区的指针后,c_void_p指针的. value