Звонящий отвечает за продвижение типа от float
до double
. Но ctypes
ничего не знает о подписи printf
, если вы не скажете это. Он не знает, что он вариативный, и что требуется продвижение типов.
Если вы не скажете ctypes
, что такое подпись функции, установив argtypes
и restype
, она предполагает int
тип возвращаемого значения, и тот параметр, который вы передали, соответствует сигнатурам. Так что в вашем случае он просто предполагает, что сигнатура printf
:
int printf(char*, double, float)
Насколько я знаю, нет способа определить переменную argtypes
в ctypes
, но это не такпохоже, все равно выполняет кастинг, даже если установлен 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