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函数。
提前多谢了~
我现在非常确定,您应该使用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_p
和c_wchar_p
的实现返回它们的名称,并且在创建指向它们的内存缓冲区的指针后,c_void_p
指针的. value
。