Wie kann ich mich übergeben, ein C++ - lambda-um einen C-callback, der erwartet, dass ein Funktionszeiger und ein Kontext?
Ich versuche, registrieren Sie einen Rückruf in einer C-API, die verwendet die standard-Funktion-Zeiger+Kontext-Paradigma. Hier ist, was die api sieht wie folgt aus:
void register_callback(void(*callback)(void *), void * context);
Was ich wirklich gerne tun, ist in der Lage, registrieren Sie einen C++ - lambda als der Rückruf. Darüber hinaus möchte ich die lambda sein, eine, die erobert hat-Variablen (dh. kann nicht konvertiert werden, um eine gerade stateless std::function
)
Welche Art von adapter code brauche ich, um schreiben zu können, registrieren Sie einen lambda-Ausdruck als callback?
- während std::function<T> ist eine Art erasure-Mechanismus, der Lage, der einen lambda-Ausdruck, es ist nicht die lambda
- Das ist fair. Habe die dicrepancy Sie daran hindern, die Frage zu verstehen? Gibt es da eine Möglichkeit, ich kann ihn neu schreiben?
- es könnte sein, dass ich noch nicht gegeben, die Frage weiter gedacht, um ganz ehrlich mit Ihnen, aber Sie umschreiben könnte sagen, dass Sie müssen ziehen Sie den Funktionszeiger aus std::function<> lieber als aus einer lambda
- Das hört sich großartig an. Gibt es eine Möglichkeit, ziehen Sie einen Rahmen dabei heraus? Eine Art von Zustand, ich konnte gehen, wie die Kontext-Zeiger auf die C-api?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den einfachen aporoach klebt man den lambda-Ausdruck in eine
std::function<void()>
ist gehalten, irgendwo. Möglicherweise ist es dem heap zugeordnet und lediglich verwiesen wird, die von dervoid*
registriert mit der Einheit unter den Rückruf. Die callback-würden Sie dann einfach eine Funktion wie diese:Beachten Sie, dass
std::function<S>
können-hold-Funktion, Objekte mit Zustand, z.B., lambda-Funktionen mit einer nicht-leeren erfassen. Sie konnte registrieren Sie einen Rückruf so:Der effizienteste Weg ist, um
voidify
die lambda direkt.hier
voidify
nimmt eine lambda-und (Optional) eine Liste der Argumente und erzeugt einen traditionellen C-Stil callback -void*
- pair-Mädchen. Dievoid*
im Besitz einerunique_ptr
mit einem speziellen deleter, damit die Ressourcen werden richtig gereinigt.Den Vorteil, dies über eine
std::function
Lösung ist die Effizienz -- ich beseitigt Ebene des run-time-Dereferenzierung. Die Lebensdauer, dass der Rückruf gilt, ist auch klar, dass es in derstd::unique_ptr<void, void(*)(void*)>
zurückgegebenvoidify
.unique_ptr<T,D>
smove
d inshared_ptr<T>
wenn Sie möchten, eine komplexere Lebensdauer.Den oben genannten Mischungen Lebensdauer mit Daten, und geben Sie die Löschung mit Dienstprogramm. Wir können es teilen:
Nun
voidify
nicht zuordnen. Einfach speichern Sie Ihre voidify für die Lebensdauer der callback übergeben Zeiger aufsecond
als Ihrevoid*
an der Seite derfirst
Funktion Zeiger.Wenn Sie brauchen, um zu speichern, dieses Konstrukt aus dem Stapel, die Umwandlung der lambda-Ausdruck ein
std::function
helfen kann. Oder verwenden Sie die erste Variante vor.Einer lambda-Funktion ist kompatibel mit C-callback-Funktion, solange es nicht erfassen Variablen.
Kraft, etwas neues zu alten mit dem neuen Weg nicht sinnvoll.
Wie wäre folgende altmodische Art und Weise?
Sehr einfache Art und Weise zu verwenden, erhalten Sie eine lamda Funktion als C-Funktion Zeiger ist dieser:
finden Sie diese Antwort für ein Beispiel. https://stackoverflow.com/a/56145419/513481