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.5k 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 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.

    kshegunovK 1 Reply Last reply
    0
    • C CCRfan

      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.

      kshegunovK Offline
      kshegunovK Offline
      kshegunov
      Moderators
      wrote on 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 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.

        kshegunovK 1 Reply Last reply
        0
        • C CCRfan

          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.

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on 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 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?

            kshegunovK 1 Reply Last reply
            0
            • C CCRfan

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

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on 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 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.

                kshegunovK 1 Reply Last reply
                0
                • C CCRfan

                  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.

                  kshegunovK Offline
                  kshegunovK Offline
                  kshegunov
                  Moderators
                  wrote on 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
                  0
                  • kshegunovK kshegunov

                    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 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.

                    kshegunovK 1 Reply Last reply
                    0
                    • C CCRfan

                      @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.

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on 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
                      0
                      • C Offline
                        C Offline
                        CCRfan
                        wrote on 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
                        • kshegunovK kshegunov

                          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 last edited by
                          #12

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

                          kshegunovK 1 Reply Last reply
                          0
                          • C CCRfan

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

                            kshegunovK Offline
                            kshegunovK Offline
                            kshegunov
                            Moderators
                            wrote on 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

                            • Login

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