Boost :: function zu einem einfachen functionszeiger herabstufen

will boost :: bind an eine Methode übergeben, die einen einfachen functionszeiger erwartet (gleiche Signatur).

typedef void TriggerProc_type(Variable*,void*); void InitVariable(TriggerProc_type *proc); boost::function triggerProc ... InitVariable(triggerProc); error C2664: 'InitVariable' : cannot convert parameter 1 from 'boost::function' to 'void (__cdecl *)(type *,void *)' 

Ich kann vermeiden, eine boost :: -function zu speichern und übergeben Sie den gebundenen Funktor direkt, aber dann bekomme ich ähnliche Fehler:

 error C2664: 'blah(void (__cdecl *)(type *,void *))' : cannot convert parameter 1 from 'boost::_bi::bind_t' to 'void (__cdecl *)(type *,void *)' 

    Hat jemand bemerkt, dass die angenommene Antwort nur mit trivialen Fällen funktioniert? Die einzige Methode, mit der die function <> :: target () ein Objekt zurückgibt, das an einen C-Callback gebunden werden kann, ist, wenn es mit einem Objekt erstellt wurde, das an einen C-Callback gebunden werden kann. Wenn das der Fall ist, dann könnten Sie es direkt gebunden haben und übersprungen alle Funktion <> Unsinn zu beginnen.

    Wenn Sie darüber nachdenken, gibt es keine magische Lösung dafür. Ein Callback im C-Stil wird als einzelner pointers gespeichert, der auf ausführbaren Code zeigt. Jede nichttriviale boost :: function <> benötigt mindestens zwei Zeiger: einen zum ausführbaren Code, den anderen zu den Daten, die zum Aufbau des Aufrufs benötigt werden (z. B. der ‘this’ -Zeiger im Fall eines gebundenen Members) Funktion).

    Der richtige Weg, boost :: function und boost :: bind mit C-Callbacks zu verwenden, besteht darin, eine Shim-function zu erstellen, die die Callback-Signatur erfüllt, herausfindet, welche function <> aufgerufen werden soll, und sie aufruft. Normalerweise haben C-Callbacks eine Art void * für ‘Benutzerdaten’; Dort speichern Sie Ihren Funktionszeiger:

     typedef void (*CallbackType)(int x, void* user_data); void RegisterCallback(CallbackType cb, void* user_data); void MyCallback(int x, void* userData) { boost::function pfn = static_cast >(userData); pfn(x); } boost::function fn = boost::bind(myFunction(5)); RegisterCallback(MyCallback, &fn); 

    Wenn Ihre Callback-Signatur keinen Benutzerdatenzeiger enthält, haben Sie natürlich kein Glück. Aber jeder Callback, der keinen Benutzerdatenzeiger enthält, ist in den meisten realen Szenarien bereits unbrauchbar und muss neu geschrieben werden.

    Ich denke du willst die target () Memberfunktion von boost :: function benutzen (ist das nicht ein Bissen …)

     #include  #include  int f(int x) { return x + x; } typedef int (*pointer_to_func)(int); int main() { boost::function g(f); if(*g.target() == f) { std::cout < < "g contains f" << std::endl; } else { std::cout << "g does not contain f" << std::endl; } return 0; } 

    kannst du es mit bind arbeiten?

     cb_t cb = *g.target(); //target returns null 

    Das ist Absicht . Grundsätzlich, da bind einen komplett anderen Typ zurückgibt, gibt es keine Möglichkeit, dass dies funktioniert. Grundsätzlich kann ein Binder-Proxy-Objekt nicht in einen C-functionszeiger umgewandelt werden (da es kein Einer ist: es ist ein functionsobjekt). Der von boost::bind Typ ist kompliziert. Der aktuelle C ++ – Standard erlaubt keine gute Art zu tun, was Sie wollen. C ++ 0x wird mit einem decltype , der hier verwendet werden kann, um so etwas zu erreichen:

     typedef decltype(bind(f, 3)) bind_t; bind_t target = *g.target(); 

    Beachten Sie, dass dies funktioniert oder nicht. Ich habe keine Möglichkeit, es zu testen.

    siehe Boost Mailing Seite [boost] [function] Problem mit target () mit boost :: mem_fn und boost :: bind

    kannst du es mit bind arbeiten?

     #include  #include  void f(int x) { (void) x; _asm int 3; } typedef void (*cb_t)(int); int main() { boost::function g = boost::bind(f, 3); cb_t cb = *g.target(); //target returns null cb(1); return 0; } 

    update: Okay, nun geht es darum, eine Methode in einen functions-Callback zu binden. Also was nun?