Variadische Funktionen mit ctypes übersetzen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Zuzu_Typ
User
Beiträge: 12
Registriert: Montag 17. Juli 2017, 22:14

Hi,

wenn in C++ eine variable Argumentenliste verwendet wird, wie kann solch eine in Python als ctypes.CFUNCTYPE argument eingebaut werden?

Beispiel:

Code: Alles auswählen

template<typename T>
T adder(T v) {
  return v;
}

template<typename T, typename... Args>
T adder(T first, Args... args) {
  return first + adder(args...);
}
oder mit va_list und Ellipse:

Code: Alles auswählen

double findAverage(int count, ...)
{
    double sum = 0;
 
    va_list list;
 
    va_start(list, count);
 
    for (int arg=0; arg < count; ++arg)
         sum += va_arg(list, int);
 
    va_end(list);
 
    return sum / count;
}
Danke für die Unterstützung,
--Zuzu_Typ--
Zuletzt geändert von Anonymous am Sonntag 30. Juli 2017, 18:42, insgesamt 2-mal geändert.
Grund: Quelltext in Codebox-Tags gesetzt.
BlackJack

@Zuzu_Typ: Also bei der Template-Funktion hast Du ja am Ende eine konkrete Funktion mit einer festen Anzahl von Argumenten wenn das Template zur Übersetzungszeit ausgewertet wurde. Und eventuell sogar gar keine Funktion wenn der Compiler die paar Additionen einfach „inlined“.

Also so etwas wie
[codebox=cpp file=Unbenannt.cpp]int x = adder(42, 23, 4711);[/code]
wird dann ja zu einer Funktion:
[codebox=cpp file=Unbenannt.cpp]int adder(int a, int b, int c) {
return a + b + c;
}[/code]
Wobei man den Namen der Funktion aus `ctypes`-Sicht allerdings nicht kennt, denn C++-Compiler veranstalten da ja üblicherweise noch „name mangling“ um Namensräume und Funktionsüberladungen möglich zu machen.

In Python ausgedrückt könnte das eventuell so aussehen:

Code: Alles auswählen

def adder(*args):
    return sum(*args)

def create_adder(c_type, argument_count)
    return CFUNCTYPE(c_type, *([c_type] * argument_count))(adder)

adder3 = create_adder(c_int, 3)
Variadische C-Funktionen kann man mit `ctypes` nicht in Python schreiben. Das gibt die zugrundeliegende `libffi` nicht her. Wenn man das wirklich benötigt, kommt man um eine kleine C-Hilfsfunktion nicht herum, die daraus einen Aufruf einer nicht-variadischen Funktion macht.
Zuzu_Typ
User
Beiträge: 12
Registriert: Montag 17. Juli 2017, 22:14

Ok und gilt das auch für das untere Beispiel mit der Ellipse, oder nur für Template Funktionen?
BlackJack

Das untere Beispiel ist eine variadische C-Funktion. Das obere nicht. Das ist ein C++-Template. Das sind technisch gesehen zwei sehr unterschiedliche Dinge. Bei dem C++-Template wüsste ich nicht mal was das mit dem definieren einer C-Funktion in Python zu tun hat. Wie sähe denn dafür eine praktische Anwendung aus?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Für eine Template Funktion gehts schlicht nicht. Die benötigt immer einen Compiler um für eine spezifische Instantiierung Code zu erzeugen. Du kannst also nur auf konkrete Instantiierungen zugreifen die auchbals Symbol exportiert sind - für ctypes mit extern C, oder mit SIP für C++.
Zuzu_Typ
User
Beiträge: 12
Registriert: Montag 17. Juli 2017, 22:14

Oh, ich bitte um Entschuldigung, das hat mit CFUNCTYPE überhaupt nichts zu tun, ich habe an etwas anderes gedacht.

Ich dachte eigentlich an eine Funktion einer Bibliothek (z.B. msvc.printf), bei der man ja normalerweise den Rückgabetyp (restype) und die Argumentenliste geben sollte,

ich habe das gerade mal bei besagter Funktion ausprobiert, man kann auch Argumente über die Argumentenliste hinaus geben, sollte man so vorgehen?
BlackJack

Ja. Variadische Funktionen *aufrufen* ist kein Problem und das würde ich genau so ”deklarieren” — die bekannten Argumente und nichts für die Auslassungspunkte. Und dann die zusätzlichen Argumente beim Aufruf übergeben. Anzahl und Typen von denen sind ja nicht bekannt, sondern hängen von der Funktion und möglicherweise den Argumenten selbst ab.
Zuzu_Typ
User
Beiträge: 12
Registriert: Montag 17. Juli 2017, 22:14

Vielen Dank,

es tut mir leid, unnötig zusätzlich Arbeit gemacht zu haben.. :|

Ich wünsch euch beiden einen schönen Tag :D
Antworten