Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Passing function pointer
Forum Updated to NodeBB v4.3 + New Features

Passing function pointer

Scheduled Pinned Locked Moved Solved C++ Gurus
13 Posts 2 Posters 12.3k 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.
  • C Offline
    C Offline
    CCRfan
    wrote on 21 Sept 2016, 19:02 last edited by kshegunov
    #1

    Hi, this is my first post in this forum, so i am not sure General and Desktop is the right place for it.
    Let me know, if it will be moved.

    I am working on an application that uses a 3D engine. The engine has a C sdk, so until now everything went well, more or less.
    Now i would like to use a statement of the engine that requires a function pointer as a parameter casted to void *. Like this in MyClass.cpp:

    MyClass::constructor() {
    ...
    }
    
    MyClass::do_this() {
    ...
    create_someth(par1, par2, (void *) function ptr, par4);
    ...
    }
    

    I had a function, also in this class, for passing like this:

    void myFunc(int p1, long p2) {
    first_line;
    second_line;
    }
    

    In the header of my class there is definition of my function:

    ...
    public:
    ...
    void myFunc(int, long);
    ...
    

    So, how should look like the proper function pointer passing in this line:

    create_someth(par1, par2, (void *) function ptr, par4);
    

    Thanks in advance.

    K 1 Reply Last reply 21 Sept 2016, 19:20
    0
    • C CCRfan
      21 Sept 2016, 19:02

      Hi, this is my first post in this forum, so i am not sure General and Desktop is the right place for it.
      Let me know, if it will be moved.

      I am working on an application that uses a 3D engine. The engine has a C sdk, so until now everything went well, more or less.
      Now i would like to use a statement of the engine that requires a function pointer as a parameter casted to void *. Like this in MyClass.cpp:

      MyClass::constructor() {
      ...
      }
      
      MyClass::do_this() {
      ...
      create_someth(par1, par2, (void *) function ptr, par4);
      ...
      }
      

      I had a function, also in this class, for passing like this:

      void myFunc(int p1, long p2) {
      first_line;
      second_line;
      }
      

      In the header of my class there is definition of my function:

      ...
      public:
      ...
      void myFunc(int, long);
      ...
      

      So, how should look like the proper function pointer passing in this line:

      create_someth(par1, par2, (void *) function ptr, par4);
      

      Thanks in advance.

      K Offline
      K Offline
      kshegunov
      Moderators
      wrote on 21 Sept 2016, 19:20 last edited by
      #2

      A function pointer is the address to the function in the .text part of the binary. Global functions and class static functions are exactly the same, because they don't carry the this pointer. They can be passed directly as callbacks. Whereas class methods and virtual methods can't they need to be bound to an object. The address of the function (as anything in C++) is given by its name, quite literally:

      class MyClass
      {
      public:
          static int someFunction(char * param1, int param2);
      }
      
      typedef int (*FunctionType)(char *, int); //< We call the pointer to function type FunctionType (the line is optional and for simplicity).
      FunctionType pointerToFunction = &MyClass::someFunction; //< Literally means get the address of MyClass::someFunction and save it in the pointerToFunction variable.
      

      To finish up anything that's of pointer type can be implicitly converted to void *, so you can use:

      create_someth(par1, par2, &MyClass::someFunction, par4);
      

      directly.

      Read and abide by the Qt Code of Conduct

      1 Reply Last reply
      0
      • C Offline
        C Offline
        CCRfan
        wrote on 21 Sept 2016, 19:44 last edited by
        #3

        Thanks for the really quick reply. It is great!

        Unfortunately, it don't want to work. I have got the following message:
        cannot convert 'void (MyClass::)(int, long)' to 'FunctionType {aka int ()(int, long)}' in initialization

        I thought maybe the type of the typedef wrong so i changed that from int to void. It is a bit better, i think but the message is just a little bit different:
        cannot convert 'void (MyClass::)(int, long)' to 'FunctionType {aka void ()(int, long)}' in initialization

        I hope you have the solution.

        K 1 Reply Last reply 21 Sept 2016, 19:48
        0
        • C CCRfan
          21 Sept 2016, 19:44

          Thanks for the really quick reply. It is great!

          Unfortunately, it don't want to work. I have got the following message:
          cannot convert 'void (MyClass::)(int, long)' to 'FunctionType {aka int ()(int, long)}' in initialization

          I thought maybe the type of the typedef wrong so i changed that from int to void. It is a bit better, i think but the message is just a little bit different:
          cannot convert 'void (MyClass::)(int, long)' to 'FunctionType {aka void ()(int, long)}' in initialization

          I hope you have the solution.

          K Offline
          K Offline
          kshegunov
          Moderators
          wrote on 21 Sept 2016, 19:48 last edited by
          #4

          @CCRfan said in Passing function pointer:

          Unfortunately, it don't want to work. I have got the following message

          Could you post the code that generates that error - the function definition, the function declaration and the line where you get the pointer and use it?

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          0
          • C Offline
            C Offline
            CCRfan
            wrote on 21 Sept 2016, 19:49 last edited by
            #5

            I don't know why changed the forum engine this:
            aka int (*)
            to this:
            aka int()
            Should i use a formatting mechanism?

            K 1 Reply Last reply 21 Sept 2016, 19:53
            0
            • C CCRfan
              21 Sept 2016, 19:49

              I don't know why changed the forum engine this:
              aka int (*)
              to this:
              aka int()
              Should i use a formatting mechanism?

              K Offline
              K Offline
              kshegunov
              Moderators
              wrote on 21 Sept 2016, 19:53 last edited by kshegunov
              #6

              Yes, most certainly. See this thread.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              0
              • C Offline
                C Offline
                CCRfan
                wrote on 21 Sept 2016, 20:05 last edited by
                #7

                The name of the function what i would like pass is: buttonClicked
                Important part from the class header file, with function declaration:

                class A8GS_Widget : public QWidget
                {
                    Q_OBJECT
                public:
                    explicit A8GS_Widget(QWidget *parent = 0);
                    ~A8GS_Widget();
                    LPDIRECT3D9 m_pD3D;
                    LPDIRECT3DDEVICE9 m_pd3dDevice;
                    ENGINE_VARS *ev;
                    void A8GS_start();
                    EVENT ShowKey(var _ScanCode);
                    void buttonClicked(int, PANEL *);
                    QWidget *A8GS_Widget_parent;
                    bool A8GS_init_stop;
                
                signals:
                
                public slots:
                    void engineStart();
                    void engineClose();
                    void engineBoxSign();
                };
                
                typedef void (*ButtonClickType)(int, PANEL *);
                ButtonClickType pointerToFunction = &A8GS_Widget::buttonClicked;
                

                Important part 1 from the cpp file, the function definition:

                void A8GS_Widget::buttonClicked(int buttonId, PANEL *panelId) {
                    qDebug() << "buttonClicked";
                    qDebug() << buttonId;
                }
                

                Important part 2 from the cpp file, where i want to pass the function as parameter:

                void A8GS_Widget::A8GS_start() {
                ...
                    pan_setbutton(pan_ize, 0, 0, 104, 226, bmap_1, bmap_1, bmap_1, NULL, (void *)(&A8GS_Widget::buttonClicked), NULL, NULL);
                ...
                

                I hope i didn't miss nothing.

                K 1 Reply Last reply 21 Sept 2016, 20:07
                0
                • C CCRfan
                  21 Sept 2016, 20:05

                  The name of the function what i would like pass is: buttonClicked
                  Important part from the class header file, with function declaration:

                  class A8GS_Widget : public QWidget
                  {
                      Q_OBJECT
                  public:
                      explicit A8GS_Widget(QWidget *parent = 0);
                      ~A8GS_Widget();
                      LPDIRECT3D9 m_pD3D;
                      LPDIRECT3DDEVICE9 m_pd3dDevice;
                      ENGINE_VARS *ev;
                      void A8GS_start();
                      EVENT ShowKey(var _ScanCode);
                      void buttonClicked(int, PANEL *);
                      QWidget *A8GS_Widget_parent;
                      bool A8GS_init_stop;
                  
                  signals:
                  
                  public slots:
                      void engineStart();
                      void engineClose();
                      void engineBoxSign();
                  };
                  
                  typedef void (*ButtonClickType)(int, PANEL *);
                  ButtonClickType pointerToFunction = &A8GS_Widget::buttonClicked;
                  

                  Important part 1 from the cpp file, the function definition:

                  void A8GS_Widget::buttonClicked(int buttonId, PANEL *panelId) {
                      qDebug() << "buttonClicked";
                      qDebug() << buttonId;
                  }
                  

                  Important part 2 from the cpp file, where i want to pass the function as parameter:

                  void A8GS_Widget::A8GS_start() {
                  ...
                      pan_setbutton(pan_ize, 0, 0, 104, 226, bmap_1, bmap_1, bmap_1, NULL, (void *)(&A8GS_Widget::buttonClicked), NULL, NULL);
                  ...
                  

                  I hope i didn't miss nothing.

                  K Offline
                  K Offline
                  kshegunov
                  Moderators
                  wrote on 21 Sept 2016, 20:07 last edited by
                  #8

                  It won't work like this. Remember I wrote that static functions can be passed as global functions (C-like functions). Methods (like buttonClicked) have to be bound to an object, which is problematic in your case, because pan_setbutton expect a C-style function, not a class method.

                  Read and abide by the Qt Code of Conduct

                  C 1 Reply Last reply 21 Sept 2016, 20:18
                  0
                  • K kshegunov
                    21 Sept 2016, 20:07

                    It won't work like this. Remember I wrote that static functions can be passed as global functions (C-like functions). Methods (like buttonClicked) have to be bound to an object, which is problematic in your case, because pan_setbutton expect a C-style function, not a class method.

                    C Offline
                    C Offline
                    CCRfan
                    wrote on 21 Sept 2016, 20:18 last edited by
                    #9

                    @kshegunov said in Passing function pointer:

                    It won't work like this. Remember I wrote that static functions can be passed as global functions (C-like functions). Methods (like buttonClicked) have to be bound to an object, which is problematic in your case, because pan_setbutton expect a C-style function, not a class method.

                    OK, and how will work?
                    If you can see any possible changes, let me share, and i can continue my work. I started to use this Qt tool since one month and i really, really like.
                    I would appreciate any good proposal.
                    Thanks in advance.

                    K 1 Reply Last reply 21 Sept 2016, 20:25
                    0
                    • C CCRfan
                      21 Sept 2016, 20:18

                      @kshegunov said in Passing function pointer:

                      It won't work like this. Remember I wrote that static functions can be passed as global functions (C-like functions). Methods (like buttonClicked) have to be bound to an object, which is problematic in your case, because pan_setbutton expect a C-style function, not a class method.

                      OK, and how will work?
                      If you can see any possible changes, let me share, and i can continue my work. I started to use this Qt tool since one month and i really, really like.
                      I would appreciate any good proposal.
                      Thanks in advance.

                      K Offline
                      K Offline
                      kshegunov
                      Moderators
                      wrote on 21 Sept 2016, 20:25 last edited by kshegunov
                      #10

                      There aren't really good solutions for that one, that's why I was reluctant to propose anything. Your best bet is to use a global pointer to pass the context. Something like this:

                      class A8GS_Widget : public QWidget
                      {
                          Q_OBJECT
                      
                          // ...
                          static void panSetButton(int, PANEL *);
                      
                      private:
                          static A8GS_Widget * currentWidget;
                      };   
                      

                      And then in the .cpp:

                      A8GS_Widget * A8GS_Widget::currentWidget = Q_NULLPTR;
                      
                      void A8GS_Widget::panSetButton(int id, PANEL * panelId)
                      {
                          Q_ASSERT(currentWidget);
                          currentWidget->buttonClicked(id, panelId)
                      }
                      
                      void A8GS_Widget::A8GS_start()
                      {
                          // ...
                          currentWidget = this;
                          pan_setbutton(pan_ize, 0, 0, 104, 226, bmap_1, bmap_1, bmap_1, NULL, &A8GS_Widget::panSetButton, NULL, NULL);
                          // ...
                      }
                      

                      It's not ideal, but it's how this problem is treated most commonly.

                      Read and abide by the Qt Code of Conduct

                      C 1 Reply Last reply 22 Sept 2016, 19:35
                      0
                      • C Offline
                        C Offline
                        CCRfan
                        wrote on 21 Sept 2016, 20:42 last edited by
                        #11

                        Thank for your will to help.
                        I feel myself lucky, because i started another way to solve the problem. It seems to me works.
                        I have made the following changes:

                        1. I added static prefix tag to the function declaration, because i forgot to that earlier
                        2. I moved the following statement from the header to the cpp as the first line of the void A8GS_Widget::A8GS_start()
                        ButtonClickType pointerToFunction = &A8GS_Widget::buttonClicked;
                        
                        1. I changed the definition here:
                        void A8GS_Widget::buttonClicked(int buttonId, PANEL *panelId)
                        

                        from int buttonId, to var buttonId.
                        And it works! I like it!
                        Only one problem remained, i got 1024 as buttonId that should be 1. I think this is my deal with the engine.
                        Thanks for the quick and kind help.
                        I am investigate a bit more, and later i set to solved this topic.

                        1 Reply Last reply
                        1
                        • K kshegunov
                          21 Sept 2016, 20:25

                          There aren't really good solutions for that one, that's why I was reluctant to propose anything. Your best bet is to use a global pointer to pass the context. Something like this:

                          class A8GS_Widget : public QWidget
                          {
                              Q_OBJECT
                          
                              // ...
                              static void panSetButton(int, PANEL *);
                          
                          private:
                              static A8GS_Widget * currentWidget;
                          };   
                          

                          And then in the .cpp:

                          A8GS_Widget * A8GS_Widget::currentWidget = Q_NULLPTR;
                          
                          void A8GS_Widget::panSetButton(int id, PANEL * panelId)
                          {
                              Q_ASSERT(currentWidget);
                              currentWidget->buttonClicked(id, panelId)
                          }
                          
                          void A8GS_Widget::A8GS_start()
                          {
                              // ...
                              currentWidget = this;
                              pan_setbutton(pan_ize, 0, 0, 104, 226, bmap_1, bmap_1, bmap_1, NULL, &A8GS_Widget::panSetButton, NULL, NULL);
                              // ...
                          }
                          

                          It's not ideal, but it's how this problem is treated most commonly.

                          C Offline
                          C Offline
                          CCRfan
                          wrote on 22 Sept 2016, 19:35 last edited by
                          #12

                          @kshegunov Thank for the real quick and expert help.
                          I am happy with that.

                          K 1 Reply Last reply 22 Sept 2016, 19:36
                          0
                          • C CCRfan
                            22 Sept 2016, 19:35

                            @kshegunov Thank for the real quick and expert help.
                            I am happy with that.

                            K Offline
                            K Offline
                            kshegunov
                            Moderators
                            wrote on 22 Sept 2016, 19:36 last edited by
                            #13

                            I'm glad I was of help. Happy coding!

                            Read and abide by the Qt Code of Conduct

                            1 Reply Last reply
                            0

                            1/13

                            21 Sept 2016, 19:02

                            • Login

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