ctypes 奇怪地处理函数中的可变参数

ctypes weird handling of variadic arguments in functions

我正在启动这个片段:

>>> from ctypes import *
>>> libc = CDLL("libc.so.6")
>>> libc.printf("%f %f\n", c_float(1.0), c_double(1.0))
0.000000 1.000000

printf 期望 double%f 但我认为浮点数在可变参数函数中被提升为双精度数,如下面的 C 代码所示:

#include<stdio.h>
int main()
{
   float a = 1.0f;
   double b = 1.0;
   printf("%f %f\n", a, b);
}

产生预期的 1.000000 1.000000.

我错过了什么吗?编译器是否在 C 代码中进行了一些隐式转换?

我使用的是 64 位机器。

调用者负责将类型从 float 提升到 double。但是 ctypesprintf 的签名一无所知,除非你告诉它。它不知道它是可变的并且需要类型提升。

如果您不通过设置 argtypesrestype 来告诉 ctypes 函数的签名是什么,它会假定 int return类型,并且您传入的任何参数都与签名匹配。因此,在您的情况下,它只是假设 printf 的签名是:

int printf(char*, double, float)

据我所知,无法在 ctypes 中定义可变参数 argtypes,但即使设置了 argtypes,它似乎也不会进行转换:

>>> from ctypes import *
>>> libc = CDLL("libc.so.6")
>>> libc.printf.argtypes = [c_char_p, c_double, c_double]
>>> libc.printf(c_char_p(b"%f %f\n"), c_double(1.0), c_float(1.0))
Traceback (most recent call last):
  File "printf.py", line 5, in <module>
    libc.printf(c_char_p(b"%f %f\n"), c_double(1.0), c_float(1.0))
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type