Ich starte dieses Snippet:
>>> 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
erwartet ein double
für %f
ABER ich dachte, Floats wurden in variadischen Funktionen zu Doubles befördert, wie der folgende C-Code zeigt:
#include<stdio.h>
int main()
{
float a = 1.0f;
double b = 1.0;
printf("%f %f\n", a, b);
}
produziert das erwartete 1.000000 1.000000
.
Vermisse ich etwas Führt der Compiler ein implizites Casting im C-Code durch?
Ich benutze eine 64-Bit-Maschine.
Der Anrufer ist für die Typwerbung von float
bis verantwortlich double
. Aber ctypes
weiß nichts über die Unterschrift von, es printf
sei denn, Sie sagen es. Es weiß nicht, dass es variadisch ist und dass eine Typförderung erforderlich ist.
Wenn Sie ctypes
durch Setzen von argtypes
und nicht erkennen, wie die Signatur einer Funktion lautet restype
, wird ein int
Rückgabetyp angenommen, und der von Ihnen übergebene Parameter stimmt mit den Signaturen überein. In Ihrem Fall wird also nur die Signatur von angenommen printf
:
int printf(char*, double, float)
Soweit ich weiß, gibt es keine Möglichkeit, eine Variable argtypes
in zu definieren ctypes
, aber es scheint sowieso kein Casting zu geben, selbst wenn festgelegt argtypes
ist:
>>> 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
Dieser Artikel stammt aus dem Internet. Bitte geben Sie beim Nachdruck die Quelle an.
Bei Verstößen wenden Sie sich bitte [email protected] Löschen.
Lass mich ein paar Worte sagen