Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. How to inform data-changed in static function?
Forum Updated to NodeBB v4.3 + New Features

How to inform data-changed in static function?

Scheduled Pinned Locked Moved Solved Mobile and Embedded
10 Posts 4 Posters 1.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bayesky
    wrote on 4 Jun 2019, 10:12 last edited by
    #1

    I have suffered from some trouble for a long time when I used hiredis in my app.
    In order to get server response, I have to write a static function as a callback function. In the function, I change some data and emit signal to inform my main thread to update display.
    The question is the emit signal must be static in callback function, but I couldn't use signal&slot(connect) when I declare the signal static.So how to inform outside in static function?

    J 1 Reply Last reply 4 Jun 2019, 10:34
    0
    • B Bayesky
      4 Jun 2019, 10:12

      I have suffered from some trouble for a long time when I used hiredis in my app.
      In order to get server response, I have to write a static function as a callback function. In the function, I change some data and emit signal to inform my main thread to update display.
      The question is the emit signal must be static in callback function, but I couldn't use signal&slot(connect) when I declare the signal static.So how to inform outside in static function?

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 4 Jun 2019, 10:34 last edited by
      #2

      hi @Bayesky

      take look at his rather old thread
      https://forum.qt.io/topic/87302/sending-static-signals-is-it-possible/5

      the possible solution, the one from @VRonin with the big warning, may be of use.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • V Offline
        V Offline
        VRonin
        wrote on 4 Jun 2019, 10:47 last edited by
        #3

        Actually there is a much cleaner solution. Say the static callback function must have signature void callBackFunction(int argument); then you declare a static function

        void fullCallBack(int argument, MyObject* emitter){
        emitter->mySignal(argument);
        }
        

        and then use std::bind to create a function that matches the required signature:

        MyObject* object = new MyObject;
        server->sendSomething("hello world",std::bind(fullCallBack,std::placeholders::_1,object));
        

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        1 Reply Last reply
        3
        • B Offline
          B Offline
          Bayesky
          wrote on 4 Jun 2019, 13:22 last edited by Bayesky 6 Apr 2019, 13:24
          #4

          @VRonin Thank you very much.
          I have define a static function with 4 parameters

          void Widget::fullCallBack(redisAsyncContext *c, void *r, void *priv, Widget* emitter){
              //print something and get some values
              emitter->mySignal(); //emit signal
          }
          

          And then I use the following codes to shrink parameters to 3.

          Widget *w = new Widget;
          std::function<void(redisAsyncContext *c, void *r, void *priv)> fun2;
          fun2 = std::bind(fullCallBack, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, w);
          

          When I use fun2 to replace subCallback,

          redisAsyncCommand(c, fun2,  (char*) "sub"*, "SUBSCRIBE foo");//send SUB command
          

          an error occur which said:

          Widget.cpp:43:5: error: no matching function for call to 'redisAsyncCommand'
          async.h:132:5: note: candidate function not viable: 
          no known conversion from 'std::function<void (redisAsyncContext *, void *, void *)>' 
          (aka 'function<void (redisAsyncContext *, void *, void *)>') to 'redisCallbackFn *'
          (aka 'void (*)(struct redisAsyncContext *, void *, void *)') for 2nd argument
          

          Are there any mistakes in use? Thank you.

          1 Reply Last reply
          0
          • V Offline
            V Offline
            VRonin
            wrote on 4 Jun 2019, 13:31 last edited by
            #5

            @Bayesky said in How to inform data-changed in static function?:

            redisAsyncCommand

            Can you show us the signature of redisAsyncCommand? Is it a C function?

            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
            ~Napoleon Bonaparte

            On a crusade to banish setIndexWidget() from the holy land of Qt

            B 1 Reply Last reply 4 Jun 2019, 13:43
            0
            • V VRonin
              4 Jun 2019, 13:31

              @Bayesky said in How to inform data-changed in static function?:

              redisAsyncCommand

              Can you show us the signature of redisAsyncCommand? Is it a C function?

              B Offline
              B Offline
              Bayesky
              wrote on 4 Jun 2019, 13:43 last edited by
              #6

              @VRonin Yes, it is a C function.

              int redisAsyncCommand(
                redisAsyncContext *ac, redisCallbackFn *fn, void *privdata,
                const char *format, ...);
              

              The function redisAsyncConnect can be used to establish a non-blocking connection to Redis. It returns a pointer to the newly created redisAsyncContext struct.
              The privdata argument can be used to curry arbitrary data to the callback from the point where the command is initially queued for execution.

              1 Reply Last reply
              0
              • V Offline
                V Offline
                VRonin
                wrote on 4 Jun 2019, 13:52 last edited by VRonin 6 Apr 2019, 15:32
                #7

                EDIT: See @SGaist answer below for the correct solution

                Yeah, the problem is that C doesn't do objects (aka functors) unfortunately. You'll have to do something ugly, declare a static Widget* emitter; and

                void fullCallBack(redisAsyncContext *c, void *r, void *priv){
                    //print something and get some values
                    emitter->mySignal(); //emit signal
                }
                

                then you can use

                emitter=w;
                redisAsyncCommand(c, fullCallBack,  (char*) "sub"*, "SUBSCRIBE foo");
                

                It looks super ugly in C++ but you need to adapt the style to what C can handle

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  Bayesky
                  wrote on 4 Jun 2019, 14:04 last edited by
                  #8

                  @VRonin I attempt to use a static Widget* emitter; as a private variable. And then

                  void fullCallBack(redisAsyncContext *c, void *r, void *priv){
                      //print something and get some values
                      //no matter declare emitter = new Widget; or not
                      emitter->mySignal(); //emit signal
                  }
                  

                  Another error occur which says

                  :-1: error: symbol(s) not found for architecture x86_64
                  :-1: error: linker command failed with exit code 1 (use -v to see invocation)
                  
                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 4 Jun 2019, 14:06 last edited by
                    #9

                    Hi,

                    The hiredis library has a Qt example.

                    Hope it helps

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    B 1 Reply Last reply 5 Jun 2019, 12:02
                    2
                    • SGaistS SGaist
                      4 Jun 2019, 14:06

                      Hi,

                      The hiredis library has a Qt example.

                      Hope it helps

                      B Offline
                      B Offline
                      Bayesky
                      wrote on 5 Jun 2019, 12:02 last edited by
                      #10

                      @SGaist @VRonin @J-Hilk
                      Thanks a lot. It works.

                      1 Reply Last reply
                      0

                      1/10

                      4 Jun 2019, 10:12

                      • Login

                      • Login or register to search.
                      1 out of 10
                      • First post
                        1/10
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved