我对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
我知道如何纠正错误:10.1应该被c_double(10.1)
替换,但为什么我应该在这里使用c_double()
函数?前两个printf
根本不需要c_string()
或c_int()
。
而且,它是“%f”,而不是“%lf”,所以我想如果我必须在这里使用ctypes函数,我应该使用c_float()而不是c_double,但是当我尝试printf("%f", c_float(10.1))
时,我得到了错误的结果:0.000000,为什么?
答案 0 :(得分:4)
无,整数,长整数,字节字符串和unicode字符串是唯一的 可以直接用作这些参数的本机Python对象 函数调用。 None作为C NULL指针传递,字节串和 unicode字符串作为指向内存块的指针传递 包含他们的数据(char *或wchar_t *)。 Python整数和Python long作为平台默认的C int类型传递,它们的值是 蒙面以适应C型。
因此,您不需要使用c_int或c_string,因为它们是“本机”python对象。
对于您的第二个问题,Wikipedia says:
f,F:正常(定点)表示法加倍。 'f'和'F'只是不同 如何打印无限数字或NaN的字符串('inf', 'inf'和'nan'代表'f','INF','INFINITY'和'NAN'代表'F')。
MSDN says“f”修饰符也是双重类型。
因此,看起来python-ctypes读取相同的文档,并考虑使用%f,你必须给出一个双倍。
答案 1 :(得分:2)
尝试printf("%f", c_double(10.1))
说明:printf()
是一个varargs函数。格式参数说明了堆栈中可以预期的类型。
问题:在查看格式时无法区分float
和double
参数,float
使用4个字节而double
使用8。所以如何可以printf()
告诉哪一个被代码推到了堆栈上?
答案:float
始终转换为double
。这样,所有浮点类型总是在堆栈上使用相同的字节数,printf()
可以找出它们的地址。