Question

There are a number of examples out there but yet I can't seem to figure out the solution to my problem. I have

class FooSource{
    ...

    void StartGetFoos(void (*callback)(vector<IFoo*>*, IAsyncResult));
    ...
}

When StartGetFoos() is called, a request it done to get Foos, saving the callback. when the request it complete (takes about 30 secs), the saved callback is called with results. I cannot change the signature of this method.

and somewhere else I have a class

class FooUser {
    ...

    void FooUser::MyCallback(vector<IFoo*>* foos, IAsyncResult result) 
    {
          // marshall to UI thread and update UI
    }

    void init()
    {
         fooUser->StartGetFoos(??????);
         // how do I pass my callback member function here?
    }
}
Was it helpful?

Solution

There's nowhere on the signature void (*callback)(vector<IFoo*>*, IAsyncResult) for you to receive a this pointer, so you can't use a member function. Instead you'll have to use a static member function:

class FooUser {
    static void MyCallback(vector<IFoo*>* foos, IAsyncResult result) 
    {
          // marshall to UI thread and update UI
    }

    void init()
    {
         fooUser->StartGetFoos(&FooUser::MyCallback);
    }
};

The issue here is that you won't be able to access any instance data on FooUser; this may or may not be a problem.

Depending on how well the API is designed, there may be a way to pass an instance pointer e.g. via IAsyncResult result.

OTHER TIPS

If IAsyncResult is a data structure that get's passed in, and then back out again for the operation, you could extend it with your own information.

class MyAsyncResult : public IAsyncResult
{
public:
   MyAsyncResult(FoorUser *sender) : sender(sender){}
   FooUser *sender;
};

Then, as ecatmur says, you can specify a static member function for the callback, but you can also make a regular member function that gets called afterwords:

Static member functions have no access to the class members, but can be specified as callbacks where a normal C function would normally be required.

class FooUser
{
    // static with no access to class members, but can be specified as a callback.
    static void MyCallback(vector<IFoo*>* foos, IAsyncResult *result) 
    {
          MyAsyncResult *res = (MyAsyncResult*)result;
          res->sender->MyCallback(foos, result);
    }

    void MyCallback(vector<IFoo*>* foos, IAsyncResult *result) 
    {
          // handle the actual callback here
    }

    void init()
    {
         IAsyncResult *res = new MyAsyncResult(this);
         fooUser->StartGetFoos(&foos, res);
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top