How can I pass a class member function as a callback?Saving function pointer in a classPass a __thiscall to a function typedefPass a member function as argumentIndicate an object's method through his pointer in C++libpcap c/c++ callback functionArduino pointer to function of classInvalid use of non-static member function when using cpp classC++ pointer to function inside a classHow a callback function can modify an object member?Pointer to member function of classHow can I profile C++ code running on Linux?What is a callback function?How do function pointers in C work?How can I pass a parameter to a setTimeout() callback?Moving callback function to a class causes an error!non-member function pointer as a callback in API to member functionStoring member function of an object as a callback function in another objectHow to pass callback function to libusb bulk transfer function in C++ ClassHow to access the correct `this` inside a callback?Passing capturing lambda as function pointer

How does "Te vas a cansar" mean "You're going to get tired"?

How can I solve for the intersection points of two ellipses?

Three legged NOT gate? What is this symbol?

(11 of 11: Meta) What is Pyramid Cult's All-Time Favorite?

Bitcoin successfully deducted on sender wallet but did not reach receiver wallet

What are the uses and limitations of Persuasion, Insight, and Deception against other PCs?

Continuous vertical line using booktabs in tabularx table?

Why isn’t SHA-3 in wider use?

The equation of motion for a scalar field in curved spacetime in terms of the covariant derivative

Loading military units into ships optimally, using backtracking

Multirow in tabularx?

Is it legal for a company to enter an agreement not to hire employees from another company?

elisp regular expression build problem

How is this kind of structure made?

Te-form and かつ and も?

Withdrew when Jimmy met up with Heath

Wherein the Shatapatha Brahmana it was mentioned about 8.64 lakh alphabets in Vedas?

Why is transplanting a specific intact brain impossible if it is generally possible?

How can I shift my job responsibilities back to programming?

The cat ate your input again!

Visa National - No Exit Stamp From France on Return to the UK

In SQL Server, why does backward scan of clustered index cannot use parallelism?

How to avoid the "need" to learn more before conducting research?

What does "sardine box" mean?



How can I pass a class member function as a callback?


Saving function pointer in a classPass a __thiscall to a function typedefPass a member function as argumentIndicate an object's method through his pointer in C++libpcap c/c++ callback functionArduino pointer to function of classInvalid use of non-static member function when using cpp classC++ pointer to function inside a classHow a callback function can modify an object member?Pointer to member function of classHow can I profile C++ code running on Linux?What is a callback function?How do function pointers in C work?How can I pass a parameter to a setTimeout() callback?Moving callback function to a class causes an error!non-member function pointer as a callback in API to member functionStoring member function of an object as a callback function in another objectHow to pass callback function to libusb bulk transfer function in C++ ClassHow to access the correct `this` inside a callback?Passing capturing lambda as function pointer






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








65















I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.



Here is what I did from my constructor:



m_cRedundencyManager->Init(this->RedundencyManagerCallBack);


This doesn't compile - I get the following error:




Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member




I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.



Any suggestions/explanation for this??



I'm using VS2008.



Thanks!!










share|improve this question
































    65















    I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.



    Here is what I did from my constructor:



    m_cRedundencyManager->Init(this->RedundencyManagerCallBack);


    This doesn't compile - I get the following error:




    Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member




    I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.



    Any suggestions/explanation for this??



    I'm using VS2008.



    Thanks!!










    share|improve this question




























      65












      65








      65


      33






      I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.



      Here is what I did from my constructor:



      m_cRedundencyManager->Init(this->RedundencyManagerCallBack);


      This doesn't compile - I get the following error:




      Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member




      I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.



      Any suggestions/explanation for this??



      I'm using VS2008.



      Thanks!!










      share|improve this question
















      I'm using an API that requires me to pass a function pointer as a callback. I'm trying to use this API from my class but I'm getting compilation errors.



      Here is what I did from my constructor:



      m_cRedundencyManager->Init(this->RedundencyManagerCallBack);


      This doesn't compile - I get the following error:




      Error 8 error C3867: 'CLoggersInfra::RedundencyManagerCallBack': function call missing argument list; use '&CLoggersInfra::RedundencyManagerCallBack' to create a pointer to member




      I tried the suggestion to use &CLoggersInfra::RedundencyManagerCallBack - didn't work for me.



      Any suggestions/explanation for this??



      I'm using VS2008.



      Thanks!!







      c++ callback function-pointers c++03






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Jan 4 at 23:35









      rsjaffe

      4,1187 gold badges16 silver badges32 bronze badges




      4,1187 gold badges16 silver badges32 bronze badges










      asked Dec 30 '08 at 13:35









      oferofer

      2,0097 gold badges32 silver badges36 bronze badges




      2,0097 gold badges32 silver badges36 bronze badges

























          9 Answers
          9






          active

          oldest

          votes


















          46














          That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.



          Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:



          m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);


          The function can be defined as follows



          static void Callback(int other_arg, void * this_pointer) 
          CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
          self->RedundencyManagerCallBack(other_arg);






          share|improve this answer



























          • Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

            – Stefan Steiger
            Mar 27 at 10:29












          • @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

            – Johannes Schaub - litb
            Mar 27 at 10:37












          • Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

            – Stefan Steiger
            Mar 27 at 16:54












          • @StefanSteiger you are right. Reworked the answer.

            – Johannes Schaub - litb
            Mar 27 at 20:50


















          105














          This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.



          The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.



          But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.



          For example:



          class A 
          public:
          A() : data(0)
          void foo(int addToData) this->data += addToData;

          int data;
          ;

          ...

          A an_a_object;
          an_a_object.foo(5);
          A::foo(&an_a_object, 5); // This is the same as the line above!
          std::cout << an_a_object.data; // Prints 10!


          How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:



          struct A 
          int data;
          ;

          void a_init(A* to_init)

          to_init->data = 0;


          void a_foo(A* this, int addToData)

          this->data += addToData;


          ...

          A an_a_object;
          a_init(0); // Before constructor call was implicit
          a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);


          Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).



          The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.



          So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:



          boost::bind docs,
          boost::function docs



          boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.



          Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.



          Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.



          C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.






          share|improve this answer






















          • 2





            This is a great answer!

            – aardvarkk
            Oct 31 '13 at 0:45






          • 5





            Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

            – mabraham
            Jun 1 '14 at 11:05






          • 1





            @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

            – Roi Danton
            Aug 5 '17 at 18:18






          • 3





            This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

            – Carson McNeil
            Aug 11 '17 at 23:10






          • 1





            @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

            – Stefan Steiger
            Mar 27 at 10:39


















          11














          This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.




          Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:



          // std::function<return_type(list of argument_type(s))>
          void Init(std::function<void(void)> f);


          Then you can create the function pointer with std::bind and pass it to Init:



          auto cLoggersInfraInstance = CLoggersInfra();
          auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
          Init(callback);


          Complete example for using std::bind with member, static members and non member functions:



          #include <functional>
          #include <iostream>
          #include <string>

          class RedundencyManager // incl. Typo ;-)

          public:
          // std::function<return_type(list of argument_type(s))>
          std::string Init(std::function<std::string(void)> f)

          return f();

          ;

          class CLoggersInfra

          private:
          std::string member = "Hello from non static member callback!";

          public:
          static std::string RedundencyManagerCallBack()

          return "Hello from static member callback!";


          std::string NonStaticRedundencyManagerCallBack()

          return member;

          ;

          std::string NonMemberCallBack()

          return "Hello from non member function!";


          int main()

          auto instance = RedundencyManager();

          auto callback1 = std::bind(&NonMemberCallBack);
          std::cout << instance.Init(callback1) << "n";

          // Similar to non member function.
          auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
          std::cout << instance.Init(callback2) << "n";

          // Class instance is passed to std::bind as second argument.
          // (heed that I call the constructor of CLoggersInfra)
          auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
          CLoggersInfra());
          std::cout << instance.Init(callback3) << "n";



          Possible output:



          Hello from non member function!
          Hello from static member callback!
          Hello from non static member callback!


          Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).






          share|improve this answer






















          • 1





            a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

            – BadK
            Oct 2 '18 at 12:11


















          3














          What argument does Init take? What is the new error message?



          Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?






          share|improve this answer
































            3














            A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.



            If your API expects a nonmember callback function, that's what you have to pass to it.






            share|improve this answer
































              3














              Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.



              Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.




              // in your CLoggersInfra constructor:
              m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);



              // in your CLoggersInfra header:
              void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);



              // in your CLoggersInfra source file:
              void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)

              ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);






              share|improve this answer


































                2














                Necromancing.

                I think the answers to date are a little unclear.



                Let's make an example:



                Supposed you have an array of pixels (array of ARGB int8_t values)



                // A RGB image
                int8_t* pixels = new int8_t[1024*768*4];


                Now you want to generate a PNG.
                To do so, you call the function toJpeg



                bool ok = toJpeg(writeByte, pixels, width, height);


                where writeByte is a callback-function



                void writeByte(unsigned char oneByte)

                fputc(oneByte, output);



                The problem here: FILE* output has to be a global variable.

                Very bad if you're in a multithreaded environment (e.g. a http-server).



                So you need some way to make output a non-global variable, while retaining the callback signature.



                The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.



                class BadIdea 
                private:
                FILE* m_stream;
                public:
                BadIdea(FILE* stream)
                this->m_stream = stream;


                void writeByte(unsigned char oneByte)
                fputc(oneByte, this->m_stream);


                ;


                And then do



                FILE *fp = fopen(filename, "wb");
                BadIdea* foobar = new BadIdea(fp);

                bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
                delete foobar;
                fflush(fp);
                fclose(fp);


                However, contrary to expectations, this does not work.



                The reason is, C++ member functions are kinda implemented like C# extension functions.



                So you have



                class/struct BadIdea

                FILE* m_stream;



                and



                static class BadIdeaExtensions

                public static writeByte(this BadIdea instance, unsigned char oneByte)

                fputc(oneByte, instance->m_stream);





                So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.



                So when you have a typedef for the writeByte procedure, and it looks like this



                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                And you have a writeJpeg signature that looks like this



                bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
                width, uint32_t height))
                ...


                it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.



                The next best thing that you can do in C++, is using a lambda-function:



                FILE *fp = fopen(filename, "wb");
                auto lambda = [fp](unsigned char oneByte) fputc(oneByte, fp); ;
                bool ok = TooJpeg::writeJpeg(lambda, image, width, height);


                However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.



                The advantage of lambda over a manual class, is that you just need to change one typedef



                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                to



                using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 


                And then you can leave everything else untouched.



                You could also use std::bind



                auto f = std::bind(&BadIdea::writeByte, &foobar);


                But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.



                So no, there is no way to pass a member function to a method that requires a static function-pointer.



                But lambdas are the easy way around, provided that you have control over the source.

                Otherwise, you're out of luck.

                There's nothing you can do with C++.



                Note:

                std::function requires #include <functional>



                However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.



                Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.



                ./configure
                make
                make install

                gcc main.c -l:libffcall.a -o ma


                main.c:



                #include <callback.h>

                // this is the closure function to be allocated
                void function (void* data, va_alist alist)

                int abc = va_arg_int(alist);

                printf("data: %08pn", data); // hex 0x14 = 20
                printf("abc: %dn", abc);

                // va_start_type(alist[, return_type]);
                // arg = va_arg_type(alist[, arg_type]);
                // va_return_type(alist[[, return_type], return_value]);

                // va_start_int(alist);
                // int r = 666;
                // va_return_int(alist, r);




                int main(int argc, char* argv[])

                int in1 = 10;

                void * data = (void*) 20;
                void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
                // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
                // void(*incrementer1)(int abc) starts to throw errors...
                incrementer1(123);
                // free_callback(callback);
                return EXIT_SUCCESS;



                And if you use CMake, add the linker library after add_executable



                add_library(libffcall STATIC IMPORTED)
                set_target_properties(libffcall PROPERTIES
                IMPORTED_LOCATION /usr/local/lib/libffcall.a)
                target_link_libraries(BitmapLion libffcall)


                or you could just dynamically link libffcall



                target_link_libraries(BitmapLion ffcall)


                Note:

                You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.






                share|improve this answer


































                  1














                  I can see that the init has the following override:



                  Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)


                  where CALLBACK_FUNC_EX is



                  typedef void (*CALLBACK_FUNC_EX)(int, void *);





                  share|improve this answer


































                    0














                    This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:




                    Don’t.



                    Because a member function is meaningless without an object to invoke
                    it on, you can’t do this directly (if The X Window System was
                    rewritten in C++, it would probably pass references to objects around,
                    not just pointers to functions; naturally the objects would embody the
                    required function and probably a whole lot more).







                    share|improve this answer



























                    • The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                      – Limited Atonement
                      Jan 12 '16 at 19:45











                    • Feel free to edit my eight year old answer :-)

                      – Onorio Catenacci
                      Jan 12 '16 at 22:06











                    • Oh yeah...duh :-)

                      – Limited Atonement
                      Jan 13 '16 at 15:55






                    • 1





                      I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                      – Onorio Catenacci
                      Jan 13 '16 at 16:04













                    Your Answer






                    StackExchange.ifUsing("editor", function ()
                    StackExchange.using("externalEditor", function ()
                    StackExchange.using("snippets", function ()
                    StackExchange.snippets.init();
                    );
                    );
                    , "code-snippets");

                    StackExchange.ready(function()
                    var channelOptions =
                    tags: "".split(" "),
                    id: "1"
                    ;
                    initTagRenderer("".split(" "), "".split(" "), channelOptions);

                    StackExchange.using("externalEditor", function()
                    // Have to fire editor after snippets, if snippets enabled
                    if (StackExchange.settings.snippets.snippetsEnabled)
                    StackExchange.using("snippets", function()
                    createEditor();
                    );

                    else
                    createEditor();

                    );

                    function createEditor()
                    StackExchange.prepareEditor(
                    heartbeatType: 'answer',
                    autoActivateHeartbeat: false,
                    convertImagesToLinks: true,
                    noModals: true,
                    showLowRepImageUploadWarning: true,
                    reputationToPostImages: 10,
                    bindNavPrevention: true,
                    postfix: "",
                    imageUploader:
                    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                    allowUrls: true
                    ,
                    onDemand: true,
                    discardSelector: ".discard-answer"
                    ,immediatelyShowMarkdownHelp:true
                    );



                    );













                    draft saved

                    draft discarded


















                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f400257%2fhow-can-i-pass-a-class-member-function-as-a-callback%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown

























                    9 Answers
                    9






                    active

                    oldest

                    votes








                    9 Answers
                    9






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes









                    46














                    That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.



                    Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:



                    m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);


                    The function can be defined as follows



                    static void Callback(int other_arg, void * this_pointer) 
                    CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
                    self->RedundencyManagerCallBack(other_arg);






                    share|improve this answer



























                    • Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                      – Stefan Steiger
                      Mar 27 at 10:29












                    • @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                      – Johannes Schaub - litb
                      Mar 27 at 10:37












                    • Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                      – Stefan Steiger
                      Mar 27 at 16:54












                    • @StefanSteiger you are right. Reworked the answer.

                      – Johannes Schaub - litb
                      Mar 27 at 20:50















                    46














                    That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.



                    Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:



                    m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);


                    The function can be defined as follows



                    static void Callback(int other_arg, void * this_pointer) 
                    CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
                    self->RedundencyManagerCallBack(other_arg);






                    share|improve this answer



























                    • Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                      – Stefan Steiger
                      Mar 27 at 10:29












                    • @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                      – Johannes Schaub - litb
                      Mar 27 at 10:37












                    • Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                      – Stefan Steiger
                      Mar 27 at 16:54












                    • @StefanSteiger you are right. Reworked the answer.

                      – Johannes Schaub - litb
                      Mar 27 at 20:50













                    46












                    46








                    46







                    That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.



                    Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:



                    m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);


                    The function can be defined as follows



                    static void Callback(int other_arg, void * this_pointer) 
                    CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
                    self->RedundencyManagerCallBack(other_arg);






                    share|improve this answer















                    That doesn't work because a member function pointer cannot be handled like a normal function pointer, because it expects a "this" object argument.



                    Instead you can pass a static member function as follows, which are like normal non-member functions in this regard:



                    m_cRedundencyManager->Init(&CLoggersInfra::Callback, this);


                    The function can be defined as follows



                    static void Callback(int other_arg, void * this_pointer) 
                    CLoggersInfra * self = static_cast<CLoggersInfra*>(this_pointer);
                    self->RedundencyManagerCallBack(other_arg);







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Mar 27 at 20:49

























                    answered Dec 30 '08 at 13:55









                    Johannes Schaub - litbJohannes Schaub - litb

                    419k105 gold badges795 silver badges1120 bronze badges




                    419k105 gold badges795 silver badges1120 bronze badges















                    • Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                      – Stefan Steiger
                      Mar 27 at 10:29












                    • @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                      – Johannes Schaub - litb
                      Mar 27 at 10:37












                    • Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                      – Stefan Steiger
                      Mar 27 at 16:54












                    • @StefanSteiger you are right. Reworked the answer.

                      – Johannes Schaub - litb
                      Mar 27 at 20:50

















                    • Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                      – Stefan Steiger
                      Mar 27 at 10:29












                    • @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                      – Johannes Schaub - litb
                      Mar 27 at 10:37












                    • Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                      – Stefan Steiger
                      Mar 27 at 16:54












                    • @StefanSteiger you are right. Reworked the answer.

                      – Johannes Schaub - litb
                      Mar 27 at 20:50
















                    Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                    – Stefan Steiger
                    Mar 27 at 10:29






                    Wile this may be a solution/workaround FOR THE OP, I fail to see how this is an answers to the actual question.

                    – Stefan Steiger
                    Mar 27 at 10:29














                    @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                    – Johannes Schaub - litb
                    Mar 27 at 10:37






                    @StefanSteiger the answer (explanation) is in the last paragraph (in essence: "a member function pointer cannot be handled like a pointer to a free function"), and the suggestion what to do else is in the other parts of my answer. It's true that it could be more elaborative. But that's OK and is why my answer didn't get as much upvotes as the other ones. Sometimes more terse answers that in essence only contains the code needed help better than longer ones, and is why my answer was accepted.

                    – Johannes Schaub - litb
                    Mar 27 at 10:37














                    Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                    – Stefan Steiger
                    Mar 27 at 16:54






                    Schaub: Yea, exactly my point. But I see - you should have written the last part first, and then said: instead, you can do this + (first part)

                    – Stefan Steiger
                    Mar 27 at 16:54














                    @StefanSteiger you are right. Reworked the answer.

                    – Johannes Schaub - litb
                    Mar 27 at 20:50





                    @StefanSteiger you are right. Reworked the answer.

                    – Johannes Schaub - litb
                    Mar 27 at 20:50













                    105














                    This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.



                    The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.



                    But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.



                    For example:



                    class A 
                    public:
                    A() : data(0)
                    void foo(int addToData) this->data += addToData;

                    int data;
                    ;

                    ...

                    A an_a_object;
                    an_a_object.foo(5);
                    A::foo(&an_a_object, 5); // This is the same as the line above!
                    std::cout << an_a_object.data; // Prints 10!


                    How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:



                    struct A 
                    int data;
                    ;

                    void a_init(A* to_init)

                    to_init->data = 0;


                    void a_foo(A* this, int addToData)

                    this->data += addToData;


                    ...

                    A an_a_object;
                    a_init(0); // Before constructor call was implicit
                    a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);


                    Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).



                    The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.



                    So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:



                    boost::bind docs,
                    boost::function docs



                    boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.



                    Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.



                    Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.



                    C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.






                    share|improve this answer






















                    • 2





                      This is a great answer!

                      – aardvarkk
                      Oct 31 '13 at 0:45






                    • 5





                      Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                      – mabraham
                      Jun 1 '14 at 11:05






                    • 1





                      @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                      – Roi Danton
                      Aug 5 '17 at 18:18






                    • 3





                      This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                      – Carson McNeil
                      Aug 11 '17 at 23:10






                    • 1





                      @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                      – Stefan Steiger
                      Mar 27 at 10:39















                    105














                    This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.



                    The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.



                    But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.



                    For example:



                    class A 
                    public:
                    A() : data(0)
                    void foo(int addToData) this->data += addToData;

                    int data;
                    ;

                    ...

                    A an_a_object;
                    an_a_object.foo(5);
                    A::foo(&an_a_object, 5); // This is the same as the line above!
                    std::cout << an_a_object.data; // Prints 10!


                    How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:



                    struct A 
                    int data;
                    ;

                    void a_init(A* to_init)

                    to_init->data = 0;


                    void a_foo(A* this, int addToData)

                    this->data += addToData;


                    ...

                    A an_a_object;
                    a_init(0); // Before constructor call was implicit
                    a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);


                    Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).



                    The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.



                    So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:



                    boost::bind docs,
                    boost::function docs



                    boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.



                    Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.



                    Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.



                    C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.






                    share|improve this answer






















                    • 2





                      This is a great answer!

                      – aardvarkk
                      Oct 31 '13 at 0:45






                    • 5





                      Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                      – mabraham
                      Jun 1 '14 at 11:05






                    • 1





                      @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                      – Roi Danton
                      Aug 5 '17 at 18:18






                    • 3





                      This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                      – Carson McNeil
                      Aug 11 '17 at 23:10






                    • 1





                      @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                      – Stefan Steiger
                      Mar 27 at 10:39













                    105












                    105








                    105







                    This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.



                    The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.



                    But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.



                    For example:



                    class A 
                    public:
                    A() : data(0)
                    void foo(int addToData) this->data += addToData;

                    int data;
                    ;

                    ...

                    A an_a_object;
                    an_a_object.foo(5);
                    A::foo(&an_a_object, 5); // This is the same as the line above!
                    std::cout << an_a_object.data; // Prints 10!


                    How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:



                    struct A 
                    int data;
                    ;

                    void a_init(A* to_init)

                    to_init->data = 0;


                    void a_foo(A* this, int addToData)

                    this->data += addToData;


                    ...

                    A an_a_object;
                    a_init(0); // Before constructor call was implicit
                    a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);


                    Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).



                    The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.



                    So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:



                    boost::bind docs,
                    boost::function docs



                    boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.



                    Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.



                    Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.



                    C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.






                    share|improve this answer















                    This is a simple question but the answer is surprisingly complex. The short answer is you can do what you're trying to do with std::bind1st or boost::bind. The longer answer is below.



                    The compiler is correct to suggest you use &CLoggersInfra::RedundencyManagerCallBack. First, if RedundencyManagerCallBack is a member function, the function itself doesn't belong to any particular instance of the class CLoggersInfra. It belongs to the class itself. If you've ever called a static class function before, you may have noticed you use the same SomeClass::SomeMemberFunction syntax. Since the function itself is 'static' in the sense that it belongs to the class rather than a particular instance, you use the same syntax. The '&' is necessary because technically speaking you don't pass functions directly -- functions are not real objects in C++. Instead you're technically passing the memory address for the function, that is, a pointer to where the function's instructions begin in memory. The consequence is the same though, you're effectively 'passing a function' as a parameter.



                    But that's only half the problem in this instance. As I said, RedundencyManagerCallBack the function doesn't 'belong' to any particular instance. But it sounds like you want to pass it as a callback with a particular instance in mind. To understand how to do this you need to understand what member functions really are: regular not-defined-in-any-class functions with an extra hidden parameter.



                    For example:



                    class A 
                    public:
                    A() : data(0)
                    void foo(int addToData) this->data += addToData;

                    int data;
                    ;

                    ...

                    A an_a_object;
                    an_a_object.foo(5);
                    A::foo(&an_a_object, 5); // This is the same as the line above!
                    std::cout << an_a_object.data; // Prints 10!


                    How many parameters does A::foo take? Normally we would say 1. But under the hood, foo really takes 2. Looking at A::foo's definition, it needs a specific instance of A in order for the 'this' pointer to be meaningful (the compiler needs to know what 'this' is). The way you usually specify what you want 'this' to be is through the syntax MyObject.MyMemberFunction(). But this is just syntactic sugar for passing the address of MyObject as the first parameter to MyMemberFunction. Similarly when we declare member functions inside class definitions we don't put 'this' in the parameter list, but this is just a gift from the language designers to save typing. Instead you have to specify that a member function is static to opt out of it automatically getting the extra 'this' parameter. If the C++ compiler translated the above example to C code (the original C++ compiler actually worked that way), it would probably write something like this:



                    struct A 
                    int data;
                    ;

                    void a_init(A* to_init)

                    to_init->data = 0;


                    void a_foo(A* this, int addToData)

                    this->data += addToData;


                    ...

                    A an_a_object;
                    a_init(0); // Before constructor call was implicit
                    a_foo(&an_a_object, 5); // Used to be an_a_object.foo(5);


                    Returning to your example, there is now an obvious problem. 'Init' wants a pointer to a function that takes one parameter. But &CLoggersInfra::RedundencyManagerCallBack is a pointer to a function that takes two parameters, it's normal parameter and the secret 'this' parameter. Thus why you're still getting a compiler error (as a side note: If you've ever used Python, this kind of confusion is why a 'self' parameter is required for all member functions).



                    The verbose way to handle this is to create a special object that holds a pointer to the instance you want and has a member function called something like 'run' or 'execute' (or overloads the '()' operator) that takes the parameters for the member function, and simply calls the member function with those parameters on the stored instance. But this would require you to change 'Init' to take your special object rather than a raw function pointer, and it sounds like Init is someone else's code. And making a special class for every time this problem comes up will lead to code bloat.



                    So now, finally, the good solution, boost::bind and boost::function, the documentation for each you can find here:



                    boost::bind docs,
                    boost::function docs



                    boost::bind will let you take a function, and a parameter to that function, and make a new function where that parameter is 'locked' in place. So if I have a function that adds two integers, I can use boost::bind to make a new function where one of the parameters is locked to say 5. This new function will only take one integer parameter, and will always add 5 specifically to it. Using this technique, you can 'lock in' the hidden 'this' parameter to be a particular class instance, and generate a new function that only takes one parameter, just like you want (note that the hidden parameter is always the first parameter, and the normal parameters come in order after it). Look at the boost::bind docs for examples, they even specifically discuss using it for member functions. Technically there is a standard function called std::bind1st that you could use as well, but boost::bind is more general.



                    Of course, there's just one more catch. boost::bind will make a nice boost::function for you, but this is still technically not a raw function pointer like Init probably wants. Thankfully, boost provides a way to convert boost::function's to raw pointers, as documented on StackOverflow here. How it implements this is beyond the scope of this answer, though it's interesting too.



                    Don't worry if this seems ludicrously hard -- your question intersects several of C++'s darker corners, and boost::bind is incredibly useful once you learn it.



                    C++11 update: Instead of boost::bind you can now use a lambda function that captures 'this'. This is basically having the compiler generate the same thing for you.







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Jan 25 at 20:37

























                    answered Dec 31 '08 at 5:52









                    Joseph GarvinJoseph Garvin

                    10.2k16 gold badges73 silver badges140 bronze badges




                    10.2k16 gold badges73 silver badges140 bronze badges










                    • 2





                      This is a great answer!

                      – aardvarkk
                      Oct 31 '13 at 0:45






                    • 5





                      Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                      – mabraham
                      Jun 1 '14 at 11:05






                    • 1





                      @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                      – Roi Danton
                      Aug 5 '17 at 18:18






                    • 3





                      This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                      – Carson McNeil
                      Aug 11 '17 at 23:10






                    • 1





                      @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                      – Stefan Steiger
                      Mar 27 at 10:39












                    • 2





                      This is a great answer!

                      – aardvarkk
                      Oct 31 '13 at 0:45






                    • 5





                      Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                      – mabraham
                      Jun 1 '14 at 11:05






                    • 1





                      @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                      – Roi Danton
                      Aug 5 '17 at 18:18






                    • 3





                      This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                      – Carson McNeil
                      Aug 11 '17 at 23:10






                    • 1





                      @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                      – Stefan Steiger
                      Mar 27 at 10:39







                    2




                    2





                    This is a great answer!

                    – aardvarkk
                    Oct 31 '13 at 0:45





                    This is a great answer!

                    – aardvarkk
                    Oct 31 '13 at 0:45




                    5




                    5





                    Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                    – mabraham
                    Jun 1 '14 at 11:05





                    Early in the answer, std::bind1st is suggested as a way to implement the solution, but the latter part of the answer is exclusively in terms of boost::bind. How can std::bind1st be used?

                    – mabraham
                    Jun 1 '14 at 11:05




                    1




                    1





                    @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                    – Roi Danton
                    Aug 5 '17 at 18:18





                    @mabraham Ok I've added a quick example though it doesn't fit the question completely (VS2008): stackoverflow.com/a/45525074/4566599

                    – Roi Danton
                    Aug 5 '17 at 18:18




                    3




                    3





                    This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                    – Carson McNeil
                    Aug 11 '17 at 23:10





                    This should be the accepted answer! The accepted answer does not actually work if you can't change the library or pass optional args.

                    – Carson McNeil
                    Aug 11 '17 at 23:10




                    1




                    1





                    @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                    – Stefan Steiger
                    Mar 27 at 10:39





                    @Joseph Garvin: Fail to see how std::bind is the answer. this requires the argument to be of type std::function instead of a normal C function pointer. just because you hide passing the this, it's not any better than the accepted answer. Well, ok, if you have source level access to the function signature in question, you can change foo* to std::function<foo_signature>, and then you only need to change this, assuming all compilers have updated to C++11, but if you don't have source access, then you're F*ED, because the signatures are incompatible. This is the same as a C++ lambda expression.

                    – Stefan Steiger
                    Mar 27 at 10:39











                    11














                    This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.




                    Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:



                    // std::function<return_type(list of argument_type(s))>
                    void Init(std::function<void(void)> f);


                    Then you can create the function pointer with std::bind and pass it to Init:



                    auto cLoggersInfraInstance = CLoggersInfra();
                    auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
                    Init(callback);


                    Complete example for using std::bind with member, static members and non member functions:



                    #include <functional>
                    #include <iostream>
                    #include <string>

                    class RedundencyManager // incl. Typo ;-)

                    public:
                    // std::function<return_type(list of argument_type(s))>
                    std::string Init(std::function<std::string(void)> f)

                    return f();

                    ;

                    class CLoggersInfra

                    private:
                    std::string member = "Hello from non static member callback!";

                    public:
                    static std::string RedundencyManagerCallBack()

                    return "Hello from static member callback!";


                    std::string NonStaticRedundencyManagerCallBack()

                    return member;

                    ;

                    std::string NonMemberCallBack()

                    return "Hello from non member function!";


                    int main()

                    auto instance = RedundencyManager();

                    auto callback1 = std::bind(&NonMemberCallBack);
                    std::cout << instance.Init(callback1) << "n";

                    // Similar to non member function.
                    auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
                    std::cout << instance.Init(callback2) << "n";

                    // Class instance is passed to std::bind as second argument.
                    // (heed that I call the constructor of CLoggersInfra)
                    auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
                    CLoggersInfra());
                    std::cout << instance.Init(callback3) << "n";



                    Possible output:



                    Hello from non member function!
                    Hello from static member callback!
                    Hello from non static member callback!


                    Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).






                    share|improve this answer






















                    • 1





                      a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                      – BadK
                      Oct 2 '18 at 12:11















                    11














                    This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.




                    Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:



                    // std::function<return_type(list of argument_type(s))>
                    void Init(std::function<void(void)> f);


                    Then you can create the function pointer with std::bind and pass it to Init:



                    auto cLoggersInfraInstance = CLoggersInfra();
                    auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
                    Init(callback);


                    Complete example for using std::bind with member, static members and non member functions:



                    #include <functional>
                    #include <iostream>
                    #include <string>

                    class RedundencyManager // incl. Typo ;-)

                    public:
                    // std::function<return_type(list of argument_type(s))>
                    std::string Init(std::function<std::string(void)> f)

                    return f();

                    ;

                    class CLoggersInfra

                    private:
                    std::string member = "Hello from non static member callback!";

                    public:
                    static std::string RedundencyManagerCallBack()

                    return "Hello from static member callback!";


                    std::string NonStaticRedundencyManagerCallBack()

                    return member;

                    ;

                    std::string NonMemberCallBack()

                    return "Hello from non member function!";


                    int main()

                    auto instance = RedundencyManager();

                    auto callback1 = std::bind(&NonMemberCallBack);
                    std::cout << instance.Init(callback1) << "n";

                    // Similar to non member function.
                    auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
                    std::cout << instance.Init(callback2) << "n";

                    // Class instance is passed to std::bind as second argument.
                    // (heed that I call the constructor of CLoggersInfra)
                    auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
                    CLoggersInfra());
                    std::cout << instance.Init(callback3) << "n";



                    Possible output:



                    Hello from non member function!
                    Hello from static member callback!
                    Hello from non static member callback!


                    Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).






                    share|improve this answer






















                    • 1





                      a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                      – BadK
                      Oct 2 '18 at 12:11













                    11












                    11








                    11







                    This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.




                    Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:



                    // std::function<return_type(list of argument_type(s))>
                    void Init(std::function<void(void)> f);


                    Then you can create the function pointer with std::bind and pass it to Init:



                    auto cLoggersInfraInstance = CLoggersInfra();
                    auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
                    Init(callback);


                    Complete example for using std::bind with member, static members and non member functions:



                    #include <functional>
                    #include <iostream>
                    #include <string>

                    class RedundencyManager // incl. Typo ;-)

                    public:
                    // std::function<return_type(list of argument_type(s))>
                    std::string Init(std::function<std::string(void)> f)

                    return f();

                    ;

                    class CLoggersInfra

                    private:
                    std::string member = "Hello from non static member callback!";

                    public:
                    static std::string RedundencyManagerCallBack()

                    return "Hello from static member callback!";


                    std::string NonStaticRedundencyManagerCallBack()

                    return member;

                    ;

                    std::string NonMemberCallBack()

                    return "Hello from non member function!";


                    int main()

                    auto instance = RedundencyManager();

                    auto callback1 = std::bind(&NonMemberCallBack);
                    std::cout << instance.Init(callback1) << "n";

                    // Similar to non member function.
                    auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
                    std::cout << instance.Init(callback2) << "n";

                    // Class instance is passed to std::bind as second argument.
                    // (heed that I call the constructor of CLoggersInfra)
                    auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
                    CLoggersInfra());
                    std::cout << instance.Init(callback3) << "n";



                    Possible output:



                    Hello from non member function!
                    Hello from static member callback!
                    Hello from non static member callback!


                    Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).






                    share|improve this answer















                    This answer is a reply to a comment above and does not work with VisualStudio 2008 but should be preferred with more recent compilers.




                    Meanwhile you don't have to use a void pointer anymore and there is also no need for boost since std::bind and std::function are available. One advantage (in comparison to void pointers) is type safety since the return type and the arguments are explicitly stated using std::function:



                    // std::function<return_type(list of argument_type(s))>
                    void Init(std::function<void(void)> f);


                    Then you can create the function pointer with std::bind and pass it to Init:



                    auto cLoggersInfraInstance = CLoggersInfra();
                    auto callback = std::bind(&CLoggersInfra::RedundencyManagerCallBack, cLoggersInfraInstance);
                    Init(callback);


                    Complete example for using std::bind with member, static members and non member functions:



                    #include <functional>
                    #include <iostream>
                    #include <string>

                    class RedundencyManager // incl. Typo ;-)

                    public:
                    // std::function<return_type(list of argument_type(s))>
                    std::string Init(std::function<std::string(void)> f)

                    return f();

                    ;

                    class CLoggersInfra

                    private:
                    std::string member = "Hello from non static member callback!";

                    public:
                    static std::string RedundencyManagerCallBack()

                    return "Hello from static member callback!";


                    std::string NonStaticRedundencyManagerCallBack()

                    return member;

                    ;

                    std::string NonMemberCallBack()

                    return "Hello from non member function!";


                    int main()

                    auto instance = RedundencyManager();

                    auto callback1 = std::bind(&NonMemberCallBack);
                    std::cout << instance.Init(callback1) << "n";

                    // Similar to non member function.
                    auto callback2 = std::bind(&CLoggersInfra::RedundencyManagerCallBack);
                    std::cout << instance.Init(callback2) << "n";

                    // Class instance is passed to std::bind as second argument.
                    // (heed that I call the constructor of CLoggersInfra)
                    auto callback3 = std::bind(&CLoggersInfra::NonStaticRedundencyManagerCallBack,
                    CLoggersInfra());
                    std::cout << instance.Init(callback3) << "n";



                    Possible output:



                    Hello from non member function!
                    Hello from static member callback!
                    Hello from non static member callback!


                    Furthermore using std::placeholders you can dynamically pass arguments to the callback (e.g. this enables the usage of return f("MyString"); in Init if f has a string parameter).







                    share|improve this answer














                    share|improve this answer



                    share|improve this answer








                    edited Aug 5 '17 at 18:22

























                    answered Aug 5 '17 at 18:16









                    Roi DantonRoi Danton

                    2,7842 gold badges26 silver badges41 bronze badges




                    2,7842 gold badges26 silver badges41 bronze badges










                    • 1





                      a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                      – BadK
                      Oct 2 '18 at 12:11












                    • 1





                      a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                      – BadK
                      Oct 2 '18 at 12:11







                    1




                    1





                    a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                    – BadK
                    Oct 2 '18 at 12:11





                    a real, real big thank you from me for this answer! I spend already over two hours of searching and trying different approaches, nothing really worked. But this one is so simple, it just worked after 1 minute.

                    – BadK
                    Oct 2 '18 at 12:11











                    3














                    What argument does Init take? What is the new error message?



                    Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?






                    share|improve this answer





























                      3














                      What argument does Init take? What is the new error message?



                      Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?






                      share|improve this answer



























                        3












                        3








                        3







                        What argument does Init take? What is the new error message?



                        Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?






                        share|improve this answer













                        What argument does Init take? What is the new error message?



                        Method pointers in C++ are a bit difficult to use. Besides the method pointer itself, you also need to provide an instance pointer (in your case this). Maybe Init expects it as a separate argument?







                        share|improve this answer












                        share|improve this answer



                        share|improve this answer










                        answered Dec 30 '08 at 13:38









                        Konrad RudolphKonrad Rudolph

                        415k105 gold badges808 silver badges1058 bronze badges




                        415k105 gold badges808 silver badges1058 bronze badges
























                            3














                            A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.



                            If your API expects a nonmember callback function, that's what you have to pass to it.






                            share|improve this answer





























                              3














                              A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.



                              If your API expects a nonmember callback function, that's what you have to pass to it.






                              share|improve this answer



























                                3












                                3








                                3







                                A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.



                                If your API expects a nonmember callback function, that's what you have to pass to it.






                                share|improve this answer













                                A pointer to a class member function is not the same as a pointer to a function. A class member takes an implicit extra argument (the this pointer), and uses a different calling convention.



                                If your API expects a nonmember callback function, that's what you have to pass to it.







                                share|improve this answer












                                share|improve this answer



                                share|improve this answer










                                answered Dec 30 '08 at 13:47









                                jalfjalf

                                212k44 gold badges302 silver badges526 bronze badges




                                212k44 gold badges302 silver badges526 bronze badges
























                                    3














                                    Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.



                                    Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.




                                    // in your CLoggersInfra constructor:
                                    m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);



                                    // in your CLoggersInfra header:
                                    void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);



                                    // in your CLoggersInfra source file:
                                    void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)

                                    ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);






                                    share|improve this answer































                                      3














                                      Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.



                                      Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.




                                      // in your CLoggersInfra constructor:
                                      m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);



                                      // in your CLoggersInfra header:
                                      void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);



                                      // in your CLoggersInfra source file:
                                      void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)

                                      ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);






                                      share|improve this answer





























                                        3












                                        3








                                        3







                                        Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.



                                        Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.




                                        // in your CLoggersInfra constructor:
                                        m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);



                                        // in your CLoggersInfra header:
                                        void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);



                                        // in your CLoggersInfra source file:
                                        void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)

                                        ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);






                                        share|improve this answer















                                        Is m_cRedundencyManager able to use member functions? Most callbacks are set up to use regular functions or static member functions. Take a look at this page at C++ FAQ Lite for more information.



                                        Update: The function declaration you provided shows that m_cRedundencyManager is expecting a function of the form: void yourCallbackFunction(int, void *). Member functions are therefore unacceptable as callbacks in this case. A static member function may work, but if that is unacceptable in your case, the following code would also work. Note that it uses an evil cast from void *.




                                        // in your CLoggersInfra constructor:
                                        m_cRedundencyManager->Init(myRedundencyManagerCallBackHandler, this);



                                        // in your CLoggersInfra header:
                                        void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr);



                                        // in your CLoggersInfra source file:
                                        void myRedundencyManagerCallBackHandler(int i, void * CLoggersInfraPtr)

                                        ((CLoggersInfra *)CLoggersInfraPtr)->RedundencyManagerCallBack(i);







                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited Dec 30 '08 at 14:00

























                                        answered Dec 30 '08 at 13:47









                                        e.Jamese.James

                                        84k33 gold badges161 silver badges205 bronze badges




                                        84k33 gold badges161 silver badges205 bronze badges
























                                            2














                                            Necromancing.

                                            I think the answers to date are a little unclear.



                                            Let's make an example:



                                            Supposed you have an array of pixels (array of ARGB int8_t values)



                                            // A RGB image
                                            int8_t* pixels = new int8_t[1024*768*4];


                                            Now you want to generate a PNG.
                                            To do so, you call the function toJpeg



                                            bool ok = toJpeg(writeByte, pixels, width, height);


                                            where writeByte is a callback-function



                                            void writeByte(unsigned char oneByte)

                                            fputc(oneByte, output);



                                            The problem here: FILE* output has to be a global variable.

                                            Very bad if you're in a multithreaded environment (e.g. a http-server).



                                            So you need some way to make output a non-global variable, while retaining the callback signature.



                                            The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.



                                            class BadIdea 
                                            private:
                                            FILE* m_stream;
                                            public:
                                            BadIdea(FILE* stream)
                                            this->m_stream = stream;


                                            void writeByte(unsigned char oneByte)
                                            fputc(oneByte, this->m_stream);


                                            ;


                                            And then do



                                            FILE *fp = fopen(filename, "wb");
                                            BadIdea* foobar = new BadIdea(fp);

                                            bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
                                            delete foobar;
                                            fflush(fp);
                                            fclose(fp);


                                            However, contrary to expectations, this does not work.



                                            The reason is, C++ member functions are kinda implemented like C# extension functions.



                                            So you have



                                            class/struct BadIdea

                                            FILE* m_stream;



                                            and



                                            static class BadIdeaExtensions

                                            public static writeByte(this BadIdea instance, unsigned char oneByte)

                                            fputc(oneByte, instance->m_stream);





                                            So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.



                                            So when you have a typedef for the writeByte procedure, and it looks like this



                                            typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                            And you have a writeJpeg signature that looks like this



                                            bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
                                            width, uint32_t height))
                                            ...


                                            it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.



                                            The next best thing that you can do in C++, is using a lambda-function:



                                            FILE *fp = fopen(filename, "wb");
                                            auto lambda = [fp](unsigned char oneByte) fputc(oneByte, fp); ;
                                            bool ok = TooJpeg::writeJpeg(lambda, image, width, height);


                                            However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.



                                            The advantage of lambda over a manual class, is that you just need to change one typedef



                                            typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                            to



                                            using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 


                                            And then you can leave everything else untouched.



                                            You could also use std::bind



                                            auto f = std::bind(&BadIdea::writeByte, &foobar);


                                            But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.



                                            So no, there is no way to pass a member function to a method that requires a static function-pointer.



                                            But lambdas are the easy way around, provided that you have control over the source.

                                            Otherwise, you're out of luck.

                                            There's nothing you can do with C++.



                                            Note:

                                            std::function requires #include <functional>



                                            However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.



                                            Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.



                                            ./configure
                                            make
                                            make install

                                            gcc main.c -l:libffcall.a -o ma


                                            main.c:



                                            #include <callback.h>

                                            // this is the closure function to be allocated
                                            void function (void* data, va_alist alist)

                                            int abc = va_arg_int(alist);

                                            printf("data: %08pn", data); // hex 0x14 = 20
                                            printf("abc: %dn", abc);

                                            // va_start_type(alist[, return_type]);
                                            // arg = va_arg_type(alist[, arg_type]);
                                            // va_return_type(alist[[, return_type], return_value]);

                                            // va_start_int(alist);
                                            // int r = 666;
                                            // va_return_int(alist, r);




                                            int main(int argc, char* argv[])

                                            int in1 = 10;

                                            void * data = (void*) 20;
                                            void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
                                            // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
                                            // void(*incrementer1)(int abc) starts to throw errors...
                                            incrementer1(123);
                                            // free_callback(callback);
                                            return EXIT_SUCCESS;



                                            And if you use CMake, add the linker library after add_executable



                                            add_library(libffcall STATIC IMPORTED)
                                            set_target_properties(libffcall PROPERTIES
                                            IMPORTED_LOCATION /usr/local/lib/libffcall.a)
                                            target_link_libraries(BitmapLion libffcall)


                                            or you could just dynamically link libffcall



                                            target_link_libraries(BitmapLion ffcall)


                                            Note:

                                            You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.






                                            share|improve this answer































                                              2














                                              Necromancing.

                                              I think the answers to date are a little unclear.



                                              Let's make an example:



                                              Supposed you have an array of pixels (array of ARGB int8_t values)



                                              // A RGB image
                                              int8_t* pixels = new int8_t[1024*768*4];


                                              Now you want to generate a PNG.
                                              To do so, you call the function toJpeg



                                              bool ok = toJpeg(writeByte, pixels, width, height);


                                              where writeByte is a callback-function



                                              void writeByte(unsigned char oneByte)

                                              fputc(oneByte, output);



                                              The problem here: FILE* output has to be a global variable.

                                              Very bad if you're in a multithreaded environment (e.g. a http-server).



                                              So you need some way to make output a non-global variable, while retaining the callback signature.



                                              The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.



                                              class BadIdea 
                                              private:
                                              FILE* m_stream;
                                              public:
                                              BadIdea(FILE* stream)
                                              this->m_stream = stream;


                                              void writeByte(unsigned char oneByte)
                                              fputc(oneByte, this->m_stream);


                                              ;


                                              And then do



                                              FILE *fp = fopen(filename, "wb");
                                              BadIdea* foobar = new BadIdea(fp);

                                              bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
                                              delete foobar;
                                              fflush(fp);
                                              fclose(fp);


                                              However, contrary to expectations, this does not work.



                                              The reason is, C++ member functions are kinda implemented like C# extension functions.



                                              So you have



                                              class/struct BadIdea

                                              FILE* m_stream;



                                              and



                                              static class BadIdeaExtensions

                                              public static writeByte(this BadIdea instance, unsigned char oneByte)

                                              fputc(oneByte, instance->m_stream);





                                              So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.



                                              So when you have a typedef for the writeByte procedure, and it looks like this



                                              typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                              And you have a writeJpeg signature that looks like this



                                              bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
                                              width, uint32_t height))
                                              ...


                                              it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.



                                              The next best thing that you can do in C++, is using a lambda-function:



                                              FILE *fp = fopen(filename, "wb");
                                              auto lambda = [fp](unsigned char oneByte) fputc(oneByte, fp); ;
                                              bool ok = TooJpeg::writeJpeg(lambda, image, width, height);


                                              However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.



                                              The advantage of lambda over a manual class, is that you just need to change one typedef



                                              typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                              to



                                              using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 


                                              And then you can leave everything else untouched.



                                              You could also use std::bind



                                              auto f = std::bind(&BadIdea::writeByte, &foobar);


                                              But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.



                                              So no, there is no way to pass a member function to a method that requires a static function-pointer.



                                              But lambdas are the easy way around, provided that you have control over the source.

                                              Otherwise, you're out of luck.

                                              There's nothing you can do with C++.



                                              Note:

                                              std::function requires #include <functional>



                                              However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.



                                              Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.



                                              ./configure
                                              make
                                              make install

                                              gcc main.c -l:libffcall.a -o ma


                                              main.c:



                                              #include <callback.h>

                                              // this is the closure function to be allocated
                                              void function (void* data, va_alist alist)

                                              int abc = va_arg_int(alist);

                                              printf("data: %08pn", data); // hex 0x14 = 20
                                              printf("abc: %dn", abc);

                                              // va_start_type(alist[, return_type]);
                                              // arg = va_arg_type(alist[, arg_type]);
                                              // va_return_type(alist[[, return_type], return_value]);

                                              // va_start_int(alist);
                                              // int r = 666;
                                              // va_return_int(alist, r);




                                              int main(int argc, char* argv[])

                                              int in1 = 10;

                                              void * data = (void*) 20;
                                              void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
                                              // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
                                              // void(*incrementer1)(int abc) starts to throw errors...
                                              incrementer1(123);
                                              // free_callback(callback);
                                              return EXIT_SUCCESS;



                                              And if you use CMake, add the linker library after add_executable



                                              add_library(libffcall STATIC IMPORTED)
                                              set_target_properties(libffcall PROPERTIES
                                              IMPORTED_LOCATION /usr/local/lib/libffcall.a)
                                              target_link_libraries(BitmapLion libffcall)


                                              or you could just dynamically link libffcall



                                              target_link_libraries(BitmapLion ffcall)


                                              Note:

                                              You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.






                                              share|improve this answer





























                                                2












                                                2








                                                2







                                                Necromancing.

                                                I think the answers to date are a little unclear.



                                                Let's make an example:



                                                Supposed you have an array of pixels (array of ARGB int8_t values)



                                                // A RGB image
                                                int8_t* pixels = new int8_t[1024*768*4];


                                                Now you want to generate a PNG.
                                                To do so, you call the function toJpeg



                                                bool ok = toJpeg(writeByte, pixels, width, height);


                                                where writeByte is a callback-function



                                                void writeByte(unsigned char oneByte)

                                                fputc(oneByte, output);



                                                The problem here: FILE* output has to be a global variable.

                                                Very bad if you're in a multithreaded environment (e.g. a http-server).



                                                So you need some way to make output a non-global variable, while retaining the callback signature.



                                                The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.



                                                class BadIdea 
                                                private:
                                                FILE* m_stream;
                                                public:
                                                BadIdea(FILE* stream)
                                                this->m_stream = stream;


                                                void writeByte(unsigned char oneByte)
                                                fputc(oneByte, this->m_stream);


                                                ;


                                                And then do



                                                FILE *fp = fopen(filename, "wb");
                                                BadIdea* foobar = new BadIdea(fp);

                                                bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
                                                delete foobar;
                                                fflush(fp);
                                                fclose(fp);


                                                However, contrary to expectations, this does not work.



                                                The reason is, C++ member functions are kinda implemented like C# extension functions.



                                                So you have



                                                class/struct BadIdea

                                                FILE* m_stream;



                                                and



                                                static class BadIdeaExtensions

                                                public static writeByte(this BadIdea instance, unsigned char oneByte)

                                                fputc(oneByte, instance->m_stream);





                                                So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.



                                                So when you have a typedef for the writeByte procedure, and it looks like this



                                                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                                And you have a writeJpeg signature that looks like this



                                                bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
                                                width, uint32_t height))
                                                ...


                                                it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.



                                                The next best thing that you can do in C++, is using a lambda-function:



                                                FILE *fp = fopen(filename, "wb");
                                                auto lambda = [fp](unsigned char oneByte) fputc(oneByte, fp); ;
                                                bool ok = TooJpeg::writeJpeg(lambda, image, width, height);


                                                However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.



                                                The advantage of lambda over a manual class, is that you just need to change one typedef



                                                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                                to



                                                using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 


                                                And then you can leave everything else untouched.



                                                You could also use std::bind



                                                auto f = std::bind(&BadIdea::writeByte, &foobar);


                                                But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.



                                                So no, there is no way to pass a member function to a method that requires a static function-pointer.



                                                But lambdas are the easy way around, provided that you have control over the source.

                                                Otherwise, you're out of luck.

                                                There's nothing you can do with C++.



                                                Note:

                                                std::function requires #include <functional>



                                                However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.



                                                Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.



                                                ./configure
                                                make
                                                make install

                                                gcc main.c -l:libffcall.a -o ma


                                                main.c:



                                                #include <callback.h>

                                                // this is the closure function to be allocated
                                                void function (void* data, va_alist alist)

                                                int abc = va_arg_int(alist);

                                                printf("data: %08pn", data); // hex 0x14 = 20
                                                printf("abc: %dn", abc);

                                                // va_start_type(alist[, return_type]);
                                                // arg = va_arg_type(alist[, arg_type]);
                                                // va_return_type(alist[[, return_type], return_value]);

                                                // va_start_int(alist);
                                                // int r = 666;
                                                // va_return_int(alist, r);




                                                int main(int argc, char* argv[])

                                                int in1 = 10;

                                                void * data = (void*) 20;
                                                void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
                                                // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
                                                // void(*incrementer1)(int abc) starts to throw errors...
                                                incrementer1(123);
                                                // free_callback(callback);
                                                return EXIT_SUCCESS;



                                                And if you use CMake, add the linker library after add_executable



                                                add_library(libffcall STATIC IMPORTED)
                                                set_target_properties(libffcall PROPERTIES
                                                IMPORTED_LOCATION /usr/local/lib/libffcall.a)
                                                target_link_libraries(BitmapLion libffcall)


                                                or you could just dynamically link libffcall



                                                target_link_libraries(BitmapLion ffcall)


                                                Note:

                                                You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.






                                                share|improve this answer















                                                Necromancing.

                                                I think the answers to date are a little unclear.



                                                Let's make an example:



                                                Supposed you have an array of pixels (array of ARGB int8_t values)



                                                // A RGB image
                                                int8_t* pixels = new int8_t[1024*768*4];


                                                Now you want to generate a PNG.
                                                To do so, you call the function toJpeg



                                                bool ok = toJpeg(writeByte, pixels, width, height);


                                                where writeByte is a callback-function



                                                void writeByte(unsigned char oneByte)

                                                fputc(oneByte, output);



                                                The problem here: FILE* output has to be a global variable.

                                                Very bad if you're in a multithreaded environment (e.g. a http-server).



                                                So you need some way to make output a non-global variable, while retaining the callback signature.



                                                The immediate solution that springs into mind is a closure, which we can emulate using a class with a member function.



                                                class BadIdea 
                                                private:
                                                FILE* m_stream;
                                                public:
                                                BadIdea(FILE* stream)
                                                this->m_stream = stream;


                                                void writeByte(unsigned char oneByte)
                                                fputc(oneByte, this->m_stream);


                                                ;


                                                And then do



                                                FILE *fp = fopen(filename, "wb");
                                                BadIdea* foobar = new BadIdea(fp);

                                                bool ok = TooJpeg::writeJpeg(foobar->writeByte, image, width, height);
                                                delete foobar;
                                                fflush(fp);
                                                fclose(fp);


                                                However, contrary to expectations, this does not work.



                                                The reason is, C++ member functions are kinda implemented like C# extension functions.



                                                So you have



                                                class/struct BadIdea

                                                FILE* m_stream;



                                                and



                                                static class BadIdeaExtensions

                                                public static writeByte(this BadIdea instance, unsigned char oneByte)

                                                fputc(oneByte, instance->m_stream);





                                                So when you want to call writeByte, you need pass not only the address of writeByte, but also the address of the BadIdea-instance.



                                                So when you have a typedef for the writeByte procedure, and it looks like this



                                                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                                And you have a writeJpeg signature that looks like this



                                                bool writeJpeg(WRITE_ONE_BYTE output, uint8_t* pixels, uint32_t 
                                                width, uint32_t height))
                                                ...


                                                it's fundamentally impossible to pass a two-address member function to a one-address function pointer (without modifying writeJpeg), and there's no way around it.



                                                The next best thing that you can do in C++, is using a lambda-function:



                                                FILE *fp = fopen(filename, "wb");
                                                auto lambda = [fp](unsigned char oneByte) fputc(oneByte, fp); ;
                                                bool ok = TooJpeg::writeJpeg(lambda, image, width, height);


                                                However, because lambda is doing nothing different, than passing an instance to a hidden class (such as the "BadIdea"-class), you need to modify the signature of writeJpeg.



                                                The advantage of lambda over a manual class, is that you just need to change one typedef



                                                typedef void (*WRITE_ONE_BYTE)(unsigned char);


                                                to



                                                using WRITE_ONE_BYTE = std::function<void(unsigned char)>; 


                                                And then you can leave everything else untouched.



                                                You could also use std::bind



                                                auto f = std::bind(&BadIdea::writeByte, &foobar);


                                                But this, behind the scene, just creates a lambda function, which then also needs the change in typedef.



                                                So no, there is no way to pass a member function to a method that requires a static function-pointer.



                                                But lambdas are the easy way around, provided that you have control over the source.

                                                Otherwise, you're out of luck.

                                                There's nothing you can do with C++.



                                                Note:

                                                std::function requires #include <functional>



                                                However, since C++ allows you to use C as well, you can do this with libffcall in plain C, if you don't mind linking a dependency.



                                                Download libffcall from GNU (at least on ubuntu, don't use the distro-provided package - it is broken), unzip.



                                                ./configure
                                                make
                                                make install

                                                gcc main.c -l:libffcall.a -o ma


                                                main.c:



                                                #include <callback.h>

                                                // this is the closure function to be allocated
                                                void function (void* data, va_alist alist)

                                                int abc = va_arg_int(alist);

                                                printf("data: %08pn", data); // hex 0x14 = 20
                                                printf("abc: %dn", abc);

                                                // va_start_type(alist[, return_type]);
                                                // arg = va_arg_type(alist[, arg_type]);
                                                // va_return_type(alist[[, return_type], return_value]);

                                                // va_start_int(alist);
                                                // int r = 666;
                                                // va_return_int(alist, r);




                                                int main(int argc, char* argv[])

                                                int in1 = 10;

                                                void * data = (void*) 20;
                                                void(*incrementer1)(int abc) = (void(*)()) alloc_callback(&function, data);
                                                // void(*incrementer1)() can have unlimited arguments, e.g. incrementer1(123,456);
                                                // void(*incrementer1)(int abc) starts to throw errors...
                                                incrementer1(123);
                                                // free_callback(callback);
                                                return EXIT_SUCCESS;



                                                And if you use CMake, add the linker library after add_executable



                                                add_library(libffcall STATIC IMPORTED)
                                                set_target_properties(libffcall PROPERTIES
                                                IMPORTED_LOCATION /usr/local/lib/libffcall.a)
                                                target_link_libraries(BitmapLion libffcall)


                                                or you could just dynamically link libffcall



                                                target_link_libraries(BitmapLion ffcall)


                                                Note:

                                                You might want to include the libffcall headers and libraries, or create a cmake project with the contents of libffcall.







                                                share|improve this answer














                                                share|improve this answer



                                                share|improve this answer








                                                edited Mar 28 at 17:27

























                                                answered Mar 27 at 17:49









                                                Stefan SteigerStefan Steiger

                                                48.3k57 gold badges281 silver badges369 bronze badges




                                                48.3k57 gold badges281 silver badges369 bronze badges
























                                                    1














                                                    I can see that the init has the following override:



                                                    Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)


                                                    where CALLBACK_FUNC_EX is



                                                    typedef void (*CALLBACK_FUNC_EX)(int, void *);





                                                    share|improve this answer































                                                      1














                                                      I can see that the init has the following override:



                                                      Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)


                                                      where CALLBACK_FUNC_EX is



                                                      typedef void (*CALLBACK_FUNC_EX)(int, void *);





                                                      share|improve this answer





























                                                        1












                                                        1








                                                        1







                                                        I can see that the init has the following override:



                                                        Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)


                                                        where CALLBACK_FUNC_EX is



                                                        typedef void (*CALLBACK_FUNC_EX)(int, void *);





                                                        share|improve this answer















                                                        I can see that the init has the following override:



                                                        Init(CALLBACK_FUNC_EX callback_func, void * callback_parm)


                                                        where CALLBACK_FUNC_EX is



                                                        typedef void (*CALLBACK_FUNC_EX)(int, void *);






                                                        share|improve this answer














                                                        share|improve this answer



                                                        share|improve this answer








                                                        edited Jun 15 at 23:27









                                                        Alexis Wilke

                                                        10.9k4 gold badges44 silver badges82 bronze badges




                                                        10.9k4 gold badges44 silver badges82 bronze badges










                                                        answered Dec 30 '08 at 13:47









                                                        oferofer

                                                        2,0097 gold badges32 silver badges36 bronze badges




                                                        2,0097 gold badges32 silver badges36 bronze badges
























                                                            0














                                                            This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:




                                                            Don’t.



                                                            Because a member function is meaningless without an object to invoke
                                                            it on, you can’t do this directly (if The X Window System was
                                                            rewritten in C++, it would probably pass references to objects around,
                                                            not just pointers to functions; naturally the objects would embody the
                                                            required function and probably a whole lot more).







                                                            share|improve this answer



























                                                            • The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                              – Limited Atonement
                                                              Jan 12 '16 at 19:45











                                                            • Feel free to edit my eight year old answer :-)

                                                              – Onorio Catenacci
                                                              Jan 12 '16 at 22:06











                                                            • Oh yeah...duh :-)

                                                              – Limited Atonement
                                                              Jan 13 '16 at 15:55






                                                            • 1





                                                              I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                              – Onorio Catenacci
                                                              Jan 13 '16 at 16:04















                                                            0














                                                            This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:




                                                            Don’t.



                                                            Because a member function is meaningless without an object to invoke
                                                            it on, you can’t do this directly (if The X Window System was
                                                            rewritten in C++, it would probably pass references to objects around,
                                                            not just pointers to functions; naturally the objects would embody the
                                                            required function and probably a whole lot more).







                                                            share|improve this answer



























                                                            • The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                              – Limited Atonement
                                                              Jan 12 '16 at 19:45











                                                            • Feel free to edit my eight year old answer :-)

                                                              – Onorio Catenacci
                                                              Jan 12 '16 at 22:06











                                                            • Oh yeah...duh :-)

                                                              – Limited Atonement
                                                              Jan 13 '16 at 15:55






                                                            • 1





                                                              I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                              – Onorio Catenacci
                                                              Jan 13 '16 at 16:04













                                                            0












                                                            0








                                                            0







                                                            This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:




                                                            Don’t.



                                                            Because a member function is meaningless without an object to invoke
                                                            it on, you can’t do this directly (if The X Window System was
                                                            rewritten in C++, it would probably pass references to objects around,
                                                            not just pointers to functions; naturally the objects would embody the
                                                            required function and probably a whole lot more).







                                                            share|improve this answer















                                                            This question and answer from the C++ FAQ Lite covers your question and the considerations involved in the answer quite nicely I think. Short snippet from the web page I linked:




                                                            Don’t.



                                                            Because a member function is meaningless without an object to invoke
                                                            it on, you can’t do this directly (if The X Window System was
                                                            rewritten in C++, it would probably pass references to objects around,
                                                            not just pointers to functions; naturally the objects would embody the
                                                            required function and probably a whole lot more).








                                                            share|improve this answer














                                                            share|improve this answer



                                                            share|improve this answer








                                                            edited Jan 13 '16 at 16:03

























                                                            answered Dec 30 '08 at 13:51









                                                            Onorio CatenacciOnorio Catenacci

                                                            11k12 gold badges67 silver badges110 bronze badges




                                                            11k12 gold badges67 silver badges110 bronze badges















                                                            • The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                              – Limited Atonement
                                                              Jan 12 '16 at 19:45











                                                            • Feel free to edit my eight year old answer :-)

                                                              – Onorio Catenacci
                                                              Jan 12 '16 at 22:06











                                                            • Oh yeah...duh :-)

                                                              – Limited Atonement
                                                              Jan 13 '16 at 15:55






                                                            • 1





                                                              I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                              – Onorio Catenacci
                                                              Jan 13 '16 at 16:04

















                                                            • The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                              – Limited Atonement
                                                              Jan 12 '16 at 19:45











                                                            • Feel free to edit my eight year old answer :-)

                                                              – Onorio Catenacci
                                                              Jan 12 '16 at 22:06











                                                            • Oh yeah...duh :-)

                                                              – Limited Atonement
                                                              Jan 13 '16 at 15:55






                                                            • 1





                                                              I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                              – Onorio Catenacci
                                                              Jan 13 '16 at 16:04
















                                                            The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                            – Limited Atonement
                                                            Jan 12 '16 at 19:45





                                                            The link is now isocpp.org/wiki/faq/pointers-to-members#memfnptr-vs-fnptr; looks like he now says "Don't". This is why link-only answers are no good.

                                                            – Limited Atonement
                                                            Jan 12 '16 at 19:45













                                                            Feel free to edit my eight year old answer :-)

                                                            – Onorio Catenacci
                                                            Jan 12 '16 at 22:06





                                                            Feel free to edit my eight year old answer :-)

                                                            – Onorio Catenacci
                                                            Jan 12 '16 at 22:06













                                                            Oh yeah...duh :-)

                                                            – Limited Atonement
                                                            Jan 13 '16 at 15:55





                                                            Oh yeah...duh :-)

                                                            – Limited Atonement
                                                            Jan 13 '16 at 15:55




                                                            1




                                                            1





                                                            I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                            – Onorio Catenacci
                                                            Jan 13 '16 at 16:04





                                                            I've modified the answer @LimitedAtonement. Thanks for pointing this out. You're totally correct that link only answers are low quality answers. But we didn't know that back in 2008 :-P

                                                            – Onorio Catenacci
                                                            Jan 13 '16 at 16:04

















                                                            draft saved

                                                            draft discarded
















































                                                            Thanks for contributing an answer to Stack Overflow!


                                                            • Please be sure to answer the question. Provide details and share your research!

                                                            But avoid


                                                            • Asking for help, clarification, or responding to other answers.

                                                            • Making statements based on opinion; back them up with references or personal experience.

                                                            To learn more, see our tips on writing great answers.




                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function ()
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f400257%2fhow-can-i-pass-a-class-member-function-as-a-callback%23new-answer', 'question_page');

                                                            );

                                                            Post as a guest















                                                            Required, but never shown





















































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown

































                                                            Required, but never shown














                                                            Required, but never shown












                                                            Required, but never shown







                                                            Required, but never shown







                                                            Popular posts from this blog

                                                            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

                                                            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

                                                            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript