Suche nach Ideen, function bindings zu definieren



  • Hallo,
    für eine GATT server library (Bluetoe) suche ich gerade nach design Ideen, um read/write handler für den Benutzer anzubieten.

    GATT ist ganz grob gesagt, so etwas wie eine Key-Value Datenbank, die auf ganz kleinen Mikrocontrollern läuft und über Bluetooth bedienbar ist. Da die Zielhardware sehr kleine Mikrocontroller sind, verbiete sich die Verwendung von dynamischem Speicher. Selbst die Verwendung von Variablen, würde ich gerne vermeiden, wenn es eine Möglichkeit gibt, Konstanten zu verwenden.

    Das Beispiel hier zeigt, das Dilemma ein wenig:

    #include <bluetoe/server.hpp>
    #include <bluetoe/service.hpp>
    
    bluetoe::att_error_codes read_handler( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size );
    
    struct static_handler {
        static bluetoe::att_error_codes read( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size );
    };
    
    struct handler {
        bluetoe::att_error_codes read( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size );
        bluetoe::att_error_codes read_c( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size ) const;
        bluetoe::att_error_codes read_v( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size ) volatile;
        bluetoe::att_error_codes read_vc( std::size_t offset, std::size_t read_size, std::uint8_t* out_buffer, std::size_t& out_size ) const volatile;
    } handler_instance;
    
    bluetoe::server<
        bluetoe::service<
            bluetoe::service_uuid< 0x8C8B4094, 0x0DE2, 0x499F, 0xA28A, 0x4EED5BC73CA9 >,
            bluetoe::characteristic<
                bluetoe::free_read_handler< static_handler::read >,
                bluetoe::free_read_handler< read_handler >,
                bluetoe::member_read_handler< handler, &handler::read, &handler_instance >,
                bluetoe::member_read_handler_c< handler, &handler::read_c, &handler_instance >,
                bluetoe::member_read_handler_v< handler, &handler::read_v, &handler_instance >,
                bluetoe::member_read_handler_vc< handler, &handler::read_vc, &handler_instance >
            >
        >
    > gatt_server;
    

    Das Template bluetoe::characteristic soll einen Handler als parameter mit bekommen und somit definiert sein, was zu tun ist, wenn ein Wert aus der "Datenbank" gelesen werden soll.

    Für freie Funktionen und member brauche ich schon mal zwei verschiedene templates, um die Funktionszeiger aufzunehmen. Für die member functions kommen dann noch optionale cv qualifier dazu.

    Könnte eine constexpr Function hier evtl. helfen?

    Wer hat eine Idee, wie man das möglichst einheitlich lösen kann? Eine Lösung im C++11 Raum wäre ideal.

    Schönen Dank im Voraus,
    Torsten



  • Mir ist dein Problem noch nicht so ganz klar. Geht es dir um die Vermeidung von Variablen oder darum read_handler zu vereinheitlichen? Variablen sehe ich momentan jedenfalls keine. Die Adresse der Funktionen und Pointer aufs Objekt sind doch alles Template Parameter und damit compilezeit Konstanten.



  • std::function und std::bind sollte dein Problem lösen ka ob man die auch ohne dynamischen Speicher nutzen kann.



  • sebi707 schrieb:

    Mir ist dein Problem noch nicht so ganz klar. Geht es dir um die Vermeidung von Variablen oder darum read_handler zu vereinheitlichen? Variablen sehe ich momentan jedenfalls keine. Die Adresse der Funktionen und Pointer aufs Objekt sind doch alles Template Parameter und damit compilezeit Konstanten.

    Ok, sorry. Habe ich mich mal wieder nicht so klar ausgedrückt. Im Beispiel oben, brauche ich 6 verschiedene templates mit 6 verschiedenen Namen. Die kann sich wahrscheinlich keiner merken. Im Idealfall gäbe es nur ein, leicht zu merkendes Konstrukt. So etwas wie std::bind, das dann aber keine Objekt erzeugt, sondern einen Typen. Ich werde mal mit constexpr und einer Funktion experimentieren, damit könnten Ausdrücke wie:

    decltype( bluetoe::bind( &handler::read_c, &handler ) )
    

    mfg Torsten



  • roflo schrieb:

    std::function und std::bind sollte dein Problem lösen ka ob man die auch ohne dynamischen Speicher nutzen kann.

    Ja, std::bind wäre cool, allerdings könnte es dynamischen Speicher verwenden, wird aber auf jeden Fall RAM belegen und lässt sich nur dann in einen Typen konvertieren, wenn man irgend wo eine statische Variable davon anlegt und die Adresse davon nimmt.


Anmelden zum Antworten