Python 3.x ctype c_wchar_p和c_char_p返回状态与ctypes doc

时间:2016-11-13 18:48:06

标签: python python-2.7 python-3.x dll ctypes

Python版

Python 3.5.2

问题

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

MEASURE_API int InitTester(char *ipAddress)

所以我需要将一个IP地址字符串(例如,192.168.100.100)从Python传递给ctypes,根据Python 3.5的ctypes doc,我尝试了c_wchar_p和c_char_p,但没有一个他们工作,我从c dll方面重新获得了错误代码。我有一些其他函数调用这个dll传递c_int,c_void_p,c_bool和其他数据类型都可以。追溯并发现c_wchar_p和c_char_p返回结果的行为与基于ctypes doc的结果不同。来自Python 3.5的ctypes doc:

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

它返回ctypes字符串。 但是我在Python控制台中执行相同cmd的结果:

>>> 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)

所以看起来orignial字符串部分可能成为内存地址。挖掘更多,并发现它是否是Python 2.x(默认编码是ASCII),然后返回显示像Python 3.5 ctypes doc所示的字符串。但是在Python 3.x(默认编码是UTF-8)中,它总是返回数字,行为与doc不同。检查多台PC。并且理解了我们可以使用.value返回原始字符串的部分。但它无法传递给必须是ctype的C函数。

问题

  • 任何人都可以提供有关行为ctypes的解释吗?
  • 以及如何解决这个问题,以便我可以在Python3.5中获得与ctype doc相同的行为,然后使调用c dll工作?

提前多多感谢〜

1 个答案:

答案 0 :(得分:0)

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

  

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

(强调我的)

所以实质上是create_string_buffer(b'192.168.100.100')

除此之外,似乎文档可能确实不在此处。 __repr__ for c_char_p and c_wchar_p的实现返回其名称,并且在创建了指向其内存缓冲区的指针后,.value指向c_void_p