简体   繁体   English

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

[英]Python 3.x ctype c_wchar_p and c_char_p return status different from ctypes doc

Python Version Python版本

Python 3.5.2 Python 3.5.2

Issue 问题

I notice this issue when I tried to call the C DLL using ctypes, the C function is something like: 当我尝试使用ctypes调用C DLL时,我注意到了这个问题,C函数类似于:

MEASURE_API int InitTester(char *ipAddress)

So I need to pass an IP address string (for example, 192.168.100.100) from Python to ctypes, according to ctypes doc of Python 3.5, I tried both c_wchar_p and c_char_p, but none of them working, I got error code retrun from c dll side. 因此,我需要将Python的IP地址字符串(例如192.168.100.100)传递给ctypes,根据Python 3.5的ctypes doc ,我尝试了c_wchar_p和c_char_p,但是它们都不起作用,我从c重新获得了错误代码dll端。 I had some other function call to this dll passing c_int, c_void_p, c_bool and other data types which are all ok. 我通过c_int,c_void_p,c_bool和其他都可以的数据类型对此dll进行了其他函数调用。 Traced back and found that the c_wchar_p and c_char_p return results behaves different from what it should be based on ctypes doc. 进行追溯,发现c_wchar_p和c_char_p返回结果的行为与基于ctypes doc的结果不同。 From the ctypes doc of Python 3.5: 从Python 3.5的ctypes文档中:

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

It return the ctypes string. 它返回ctypes字符串。 But my results of execute the same cmd in Python console: 但是我在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)

So seems like the orignial string part becomes memory address maybe. 因此似乎原始字符串部分可能成为内存地址。 Digged in more, and found out if it is Python 2.x(default encoding is ASCII), then the return shows the string like the Python 3.5 ctypes doc shows. 深入研究,发现是否为Python 2.x(默认编码为ASCII),则返回结果显示的字符串类似于Python 3.5 ctypes doc所示。 But in Python 3.x(default encoding is UTF-8), it always return numbers, behave differnt from the doc. 但是在Python 3.x(默认编码为UTF-8)中,它总是返回数字,其行为与文档不同。 Checked on multiple PCs. 在多台PC上检查。 And understood the part that, we can use .value to return the original string. 并了解了可以使用.value返回原始字符串的部分。 But it could not pass to the C function which has to be a ctype. 但是它不能传递给必须是ctype的C函数。

Question

  • Can anyone provide a explaination about this about behavior ctypes? 谁能提供有关行为ctype的解释?
  • and how to resolve this, so that I could get the same behave like ctype doc in Python3.5 and then make the call c dll work? 以及如何解决此问题,以便在Python3.5中获得与ctype doc相同的行为,然后使调用c dll起作用?

Thanks a lot in advance~ 提前谢谢〜

I am more than certain now that you should be using create_string_buffer instead of c_char_p for passing the string to your C function; 现在,我非常确定您应该使用create_string_buffer而不是c_char_p来将字符串传递给C函数。 the non- const signature indicates a mutation and that requires a character buffer as stated in the docs: const签名表示突变,并且需要docs中所述的字符缓冲区:

You should be careful, however, not to pass them to functions expecting pointers to mutable memory. 但是,您应该小心, 不要将它们传递给期望指向可变内存的指针的函数。 If you need mutable memory blocks, ctypes has a create_string_buffer() function which creates these in various ways. 如果您需要可变的内存块,则ctypes具有一个create_string_buffer()函数,该函数可以通过各种方式创建它们。 The current memory block contents can be accessed (or changed) with the raw property; 可以使用raw属性访问(或更改)当前存储块的内容。 if you want to access it as NUL terminated string, use the value property. 如果要以NUL终止的字符串访问它,请使用value属性。

(emphasis mine) (强调我的)

So in essence, create_string_buffer(b'192.168.100.100') . 因此从本质上讲, create_string_buffer(b'192.168.100.100')

Aside from that, it just seems that the documentation might indeed be off on this. 除此之外,似乎文档可能确实不适用。 The implementation of __repr__ for c_char_p and c_wchar_p returns their name and, after a pointer to their memory buffer has been created, the .value that c_void_p pointer. 实施__repr__c_char_pc_wchar_p返回他们的名字,并已创建一个指向自己的内存缓冲区之后, .valuec_void_p指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM