Python和ctypes:为什么printf(";%f";,10.1)是错误的

Python和ctypes:为什么printf(";%f";,10.1)是错误的,python,printf,ctypes,Python,Printf,Ctypes,我对python中的ctypes有一个问题 from ctypes import * printf = cdll.msvcrt.printf printf("%s\n", "Hello World!") printf("%d\n", 100) printf("%f\n", 10.1) 结果: Hello World! 100 Traceback (most recent call last): File "C:\Users\Windows7\Desktop\test.py", line 5

我对python中的ctypes有一个问题

from ctypes import *
printf = cdll.msvcrt.printf
printf("%s\n", "Hello World!")
printf("%d\n", 100)
printf("%f\n", 10.1)
结果:

Hello World!
100
Traceback (most recent call last):
  File "C:\Users\Windows7\Desktop\test.py", line 5, in <module>
    printf("%f\n", 10.1)
ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: Don't know how to convert parameter 2
你好,世界!
100
回溯(最近一次呼叫最后一次):
文件“C:\Users\Windows7\Desktop\test.py”,第5行,在
printf(“%f\n”,10.1)
ctypes.ArgumentError:参数2::不知道如何转换参数2
我知道如何纠正这个错误:10.1应该被
c\u-double(10.1)
取代,但是为什么我要在这里使用
c\u-double()
函数呢?前两个
printf
根本不需要
c_string()
c_int()

更重要的是,它是“%f”,而不是“%lf”,所以我想如果我必须在这里使用ctypes函数,我应该使用c_float()而不是c_double,但是当我尝试
printf(“%f”,c_float(10.1))
时,我得到了错误的结果:0.000000,为什么?

根据:

无、整数、长、字节字符串和unicode字符串是唯一的 本机Python对象,可直接用作这些 函数调用。None作为C空指针、字节字符串和 unicode字符串作为指向 包含它们的数据(char*或wchar\u t*)。Python整数和Python long作为平台默认的C int类型传递,其值为 蒙面以适合C类型

因此,不需要使用c_int或c_string,因为它们是“本机”python对象

关于第二个问题:

f、 f:标准(定点)表示法中的双精度f'和“f”只是不同而已 如何打印无限数或NaN的字符串('inf', “infinity”和“nan”表示“f”,“INF”,“infinity”和“nan”表示“f”)

“f”修饰符也适用于双精度类型

PythCyType看起来是相同的文档,并且考虑到一% f必须给出一个双倍值。

< P>尝试<代码> PrimTf(“%F”,CyBug(10.1))< /C> < /P> 说明:
printf()
是一个varargs函数。格式参数解释了堆栈上可以使用的类型

问题:在查看格式时,无法区分
float
double
参数,但是
float
使用4字节,而
double
使用8字节。那么,
printf()
如何分辨代码在堆栈上推了哪一个呢


回答:
float
s始终转换为
double
。这样,所有浮点类型在堆栈上总是使用相同的字节数,
printf()
可以计算出它们的地址。

有趣的是:printf(“%d\n”,100)为我显示一个0,而不是100(Python 3.2.2),非常感谢。但是为什么我不能使用
printf(“%f”,c\u float(10.1))
?@MarkZar:我在Wikipédia中找到了一个解释,如我的答案版所示。非常感谢,但我不知道printf的实现原理,在我看来,printf不能检查格式参数以确定是否在堆栈上推送了float或double吗?e、 g如果printf发现format参数为
%f
,则将附加参数视为浮点,如果
%lf
,则视为双精度。它不能这样做吗?这是1970年代的代码。在那个时代,空间是宝贵的,之后的一切都必须向后兼容。原始实现只接受
%f
%e
%g
中任何一种的双重类型。请参阅
l
仅适用于整数类型。非常感谢您的帮助。我已经收到了。