Aem*_*myl 38 python ctypes python-2.7
我试图printf()
在Linux上的python命令行中使用C函数.为了完成这项工作,我导入了ctypes
.我的问题是:如果我创建一个在循环中CDLL
使用printf()
-function 的对象,我得到一个非常奇怪的输出:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> for i in range(10):
... libc.printf("%d", i)
...
01
11
21
31
41
51
61
71
81
91
>>>
Run Code Online (Sandbox Code Playgroud)
但是,当我在函数内部调用此循环时,它按预期工作:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6")
>>> def pr():
... for i in range(10):
... libc.printf("%d", i)
... libc.printf("\n")
...
>>> pr()
0123456789
>>>
Run Code Online (Sandbox Code Playgroud)
我猜不出是什么导致了这种行为......
如果重要的话,我在Linux上使用Python 2.7.6.
编辑:
Python版本/操作系统对此没有影响.有关详细信息,请参阅下面的PM 2Ring的答案.在Windows上,您只需将初始化更改libc
为libc = ctypes.CDLL("msvcrt.dll")
where .dll
是可选的.获取正确输出比调用函数的另一种方法是将printf()
变量值存储在变量中:
>>> import ctypes
>>> libc = ctypes.CDLL("libc.so.6") # "mscvrt.dll" on windows
>>> for i in range(10):
... r = libc.printf("%d", i)
...
0123456789>>>
Run Code Online (Sandbox Code Playgroud)
我仍然更喜欢这个功能,因为你可以更容易地添加一个结束的换行符.
PM *_*ing 85
'1'
每个数字末尾的额外值是返回值printf
,返回它打印的字符数.将自动打印在交互式解释器中调用的函数的返回值(除非它是None
).
事实上,交互式解释器打印任何None
未分配的非表达式.当然,它为这些表达式添加了一个换行符,这解释了为什么第一个代码块中的输出位于不同的行上.
您的pr
函数没有return语句,因此返回None
,因此不会打印额外的东西.
虽然PM 2Ring已经很好地回答了这个问题,但我认为值得指出的是printf的行为或非常接近的行为可以作为内置的python使用,所以你使用C库版本真的很奇怪,除非你用它来学习如何使用ctypes
,在这种情况下继续.
但另一方面,ctypes
当你没有使用足够的python知道REPL是如何工作的时候想要使用它是很奇怪的...冒着傲慢的风险,就像有10年python经验的人一样,我从来没有不得不用ctypes
.
python中有两个用于字符串格式化的内置选项:
print("%d" % (i,))
Run Code Online (Sandbox Code Playgroud)
这是旧式的,与printf非常相似,而且
print("{:d}".format(i))
Run Code Online (Sandbox Code Playgroud)
这是python 3的新功能,并且功能更强大.有关于解决本网站差异的问题.以上两行都将输出相同的libc.printf("%d\n", i)
.也可以在没有换行的情况下进行打印.
CPython的实现"%"字符串格式化的实际使用sprintf的引擎盖下.