使用ctypes时libc.strlen总是返回1?

时间:2012-06-13 20:10:16

标签: python ctypes

我有一个使用ctypes的简单代码:

Python 3.1.1 (r311:74480, Feb 23 2010, 11:06:41)
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> libc.strlen("HELLO")
1
>>> print(libc.strlen("HELLO"))
1

我做错了什么?。

提前致谢。

4 个答案:

答案 0 :(得分:2)

Python 3使用Unicode作为字符串。当传递给C函数时,每个字符将超过一个字节,对于ASCII字符,其中一个字节将为零。 strlen将停在它找到的第一个零点。

我能够在Python 2.7中复制这些结果以及修复:

>>> libc.strlen("HELLO")
5
>>> libc.strlen(u"HELLO")
1
>>> libc.strlen(u"HELLO".encode('ascii'))
5

答案 1 :(得分:2)

使用ctypes最好告诉它参数的类型,它会在你弄错它时告诉你:

Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> libc = ctypes.CDLL("msvcrt")
>>> libc.strlen('hello')
1
>>> libc.strlen.argtypes=[ctypes.c_char_p]
>>> libc.strlen('hello')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

在Python 3中,字符串是默认的Unicode。 b''语法是字节字符串,这是strlen的工作原理:

>>> libc.strlen(b'hello')
5

至少在Windows上,有很多版本的strlen:

>>> libc.wcslen.argtypes=[ctypes.c_wchar_p]
>>> libc.wcslen('hello')
5

答案 2 :(得分:0)

$ python
Python 2.7.3 (default, Apr 20 2012, 22:39:59)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import ctypes
>>> libc = ctypes.CDLL('libc.so.6')
>>> libc.strlen('HELLO')
5

您的Python或gcc版本是否需要在libc.strlen('HELLO\0')中明确NUL终止?

答案 3 :(得分:0)

奇怪......用它有效!。

>>> libc.strlen(b'HELLO')
5