std::function in ein Funktions-Pointer umwandeln [Erledigt]



  • Hallo,
    ich habe eine externe C-Lib dessen Quellcode ich ebenfalls modifizieren kann.
    Die C-Lib sucht durch eine for-Schleife nach möglichen Barcode-Regionen. Da dies unter Umständen recht lange dauern kann, habe ich das C-Interface mit einem Callback erweitert mit dem man die Suche abbrechen kann:

    extern DmtxRegion *dmtxRegionFindNext(DmtxDecode *dec,  bool (*continueWithTaskCallback)());
    

    In der for-Schleife wird continueWithTaskCallback() als Condition hinzugefügt.

    Um die C-Lib habe ich einen C++ Wrapper entwickelt, der allerdings std::function<bool()> als Callback nutzt. Jetzt stellt sich die Frage, wie ich std::function<bool()> ohne static Funktionen in ein Funktions-Pointer umwandeln kann, damit ich kompatibel mit der C-Lib bleibe.

    Eine andere Möglichkeit wäre, die C-Lib mit einem C++ Compiler zu kompilieren und dort ebenfalls std::function<bool()> zu verwenden. Allerdings weiß ich nicht, ob das eine gute Idee ist.

    Jemand Anregungen und Tipps?

    PS: Ich bin an möglichst einfachen Lösungen interessiert. Irgendwo im Web habe ich eine sehr komplizierte Template-Lösung gefunden. Wenn man von anderen Programmiersprachen kommt, kann man kaum glauben, dass etwas so einfaches so kompliziert sein muss. Der Code muss ja auch gewartet werden und zu kompliziert darf die Lösung deshalb nicht sein.

    Danke im Voraus!
    Steffo


  • Mod

    Du kannst auch eine altmodische Lösung einsetzen. Der Callback nimmt einen void* als Parameter (closure), und dmtxRegionFindNext wird ein solcher Pointer übergeben, der dann an den Callback weitergegeben wird.



  • Hi Columbo,
    du meinst so etwas?
    Aber ich brauche ja eine bool-Rückgabe für die for-Bedingung. Wie soll das gehen?

    Viele Grüße,
    Steffo



  • @Steffo sagte in std::function in ein Funktions-Pointer umwandeln:

    Eine andere Möglichkeit wäre, die C-Lib mit einem C++ Compiler zu kompilieren und dort ebenfalls std::function<bool()> zu verwenden. Allerdings weiß ich nicht, ob das eine gute Idee ist.

    Wenn du keinen konkreten Grund hast, bei C zu bleiben: warum nicht?



  • Ich glaube, so langsam gebe ich auf. Weder schaffe ich es ohne static Funktion zum Laufen zu bringen, trotz stundenlanger Recherche, noch gelingt es mir die C-Lib mit std::function Interface zum Laufen zu bringen ("Fehler: functional: No such file or directory"). O.o


  • Mod

    @Steffo Was hat der Rueckgabetyp mit dem Parameter zu tun?



  • Was @Columbo meint ist folgendes:

    DmtxRegion *dmtxRegionFindNext(DmtxDecode *dec,  bool (*continueWithTaskCallback)(void*), void *userdata)
    {
      // ...
      continueWithTaskCallback(userdata);
      // ...
    }
    

    Und dann kannst du von C++ aus als userdata einen Zeiger auf das Klassenobjekt übergeben.
    So mußt du zwar eine statische Helperfunktion an die C-Funktion übergeben, kannst aber dann in der Callback-Funktion dann wiederum auf das Klassenobjekt zugreifen:

    // Aufruf innerhalb der Klasse MyClass
    dmtxRegionFindNext(dec, &MyCallback, this);
    
    /*static*/ bool MyCallback(void *userdata) // static, falls Klassenfunktion
    {
      MyClass *x = static_cast<MyClass>(userdata);
      return x->DoSomething();
    }
    

    Mittels std::function<T>kannst du keine nicht-statische Funktion an eine C-Funktion übergeben (da C keine Klassen kennt).

    PS: Mit "komplizierte Template-Lösung" meinst du die 2. Antwort in Using a C++ class member function as a C callback function?



  • @Steffo sagte in std::function in ein Funktions-Pointer umwandeln:

    Fehler: functional: No such file or directory

    Der Compiler übersetzt vermutlich immer noch als C.



  • @Th69 Wow! Das ist wirklich ausgeklügelt und funktioniert tatsächlich. Vielen Dank!!!
    Ja, das ist einer der komplizierten Template-Lösungen, die ich im Web gefunden habe.



  • Nochmals danke! Ich freue mich sehr über die Lösung. Dadurch ist meine Wrapper-Klasse thread-safe und kann auch für Multi-Threading verwendet werden! 🙂
    Eine gute Community sollte man niemals unterschätzen!


Anmelden zum Antworten