Functoren und C Callbacks
-
Ich versuche gerade eine C Library zu wrappen und mit einem schönen C++ Interface zu versehen. Nun steh ich vor einem Problem, bei einer Funktion, die es ermöglicht Funktionen in die Library einzufügen. Leider kann man nur Funktionspointer übergeben, da es sich eben um eine C Library handelt. Ich will nun aber ein boost::function Objekt nehmen und irgend wie als Callback benutzen. Leider kann man nicht einen Parameter angeben, der der C Funktion beim aufruf mit übergeben wird.
Naja, hier ist ein bisschen Code, der das wahrscheinlich besser erklärt
struct wrapper { void add_function(const std::string &name,const boost::function<void()> &f) { rb_add_func(name.c_str(), /*hier will ich nun ein Callback übergeben, was im Endeffekt f aufruft*/ ); } };
Ich dachte erst daran, dass ich eine Template Funktion schreibe, die als Templateparameter f bekommt und mir dann eine Funktion generiert, die ich als Callback nutzen kann. Aber leider kann man Template-Parameter nicht so benutzen, wie ich es mir erhofft habe.
Hat irgend jemand von euch eine Idee, was ich hier machen könnte?
-
von der boost site:
Boost.Function vs. Function Pointers
Boost.Function has several advantages over function pointers, namely:
- Boost.Function allows arbitrary compatible function objects to be targets (instead of requiring an exact function signature).
- Boost.Function may be used with argument-binding and other function object construction libraries.
- Boost.Function has predictible behavior when an empty function object is called.
And, of course, function pointers have several advantages over Boost.Function:
- Function pointers are smaller (the size of one pointer instead of three)
- Function pointers are faster (Boost.Function may require two calls through function pointers)
- Function pointers are backward-compatible with C libraries.
- More readable error messages.
das klingt für mich so, dass es von boost::function keinen weg zu c gibt,
da sie auch für komplexere sachen benutzt werden können als ein functionpointerhier steht ein kurze info dazu: http://lists.boost.org/MailArchives/boost-users/msg02989.php
-
ich dachte auch eher daran, ein Wrapper zu schreiben, der mit einem Funktionspointer aufgerufen wird und dann intern boost::function benutzt.
Bei einer anderen API kann ich zB. einen void Pointer übergeben und da übergeb ich einfach das boost::function Objekt
namespace { void wrapper_callback(void *ptr) { boost::function<void ()> f)*reinterpret_cast<boost::function<void ()>*>(ptr); f(); } void clean_up(void *ptr) { delete reinterpret_cast<boost::function<void ()>*>(ptr); } } void foo::add_function(const std::string &name,const boost::function<void ()> &f) { foo_add_function(blub,name.c_str(),wrapper_callback,new boost::function<void ()>(f),clean_up); }
-
Ich hab leider so ziemlich das selbe Problem, bin aber noch auf der suche.
Vielleicht hilft dir das weiter:
http://lgdc.sunsite.dk/articles/5.html