views:

491

answers:

2

Trying to integrate plain C/C++ code into iPhone project as an external static library. So far so good, but now I'm stuck at a point, where I need to register library callbacks. The library should notify my iPhone application, when something happens. Seems like a good place to define a Delegate.

...but the library is expecting C function pointers for callbacks. How do I define those in Objective-C, how do I use those as part of delegate pattern?

Sorry, really can't give sample code. Here's something bit similar: first interface I got to use to register, followed by definitions of callbacks.

registerCallBack(&aCBack, &bCBack, &cCBack, &dCBack, &eCBack);

typedef void (aCBack)(uint32_t magic);
typedef void (bCBack)(const NewData* newData);
typedef void (cCBack)(uint32_t value, const std::vector<DataStuff*>* stuff);
typedef void (dCBack)(uint32_t value, const SomeData* data, const std::string text, uint32_t type);
typedef void (eCBack)(uint32_t value, const MoreData* more);

...oh btw, one of the problems is that each Objective-C class method has two hidden arguments. Not sure how to deal with that at all. Besides changing interface of that external library.

+4  A: 

You need to use C++/C interfaces for the callbacks which then internally delegate the call to your Objective-C code. Where the callback registrations allow you to pass in user-data of sufficient size, you can conveniently pass something that identifies your context like in this answer.
Callbacks that don't get passed any context have to call a class method of your Objective-C part anyway.

Georg Fritzsche
Reading this many times, each time understanding a bit more :) Wondering how to do the **"internally delegate the call to your Objective-C code"**? Looking at singleton design pattern, lots of work. Is there any other ways?
JOM
If you can sink the call to C++ class, this class' implementation can contain Objective-C code - so you can call an e.g. Objective-C class that your C++ instance contains an `id` for or similar. It really depends on the mentioned ability to hand a context around and the specific use-case :)
Georg Fritzsche
+1  A: 

You have to use plain C functions for this, but you can call through to your delegate object from them as long as you're compiling as Objective-C:

// need to have a reference to the object, of course
static DelegateClass* delegate = NULL;

// call at runtime with your actual delegate
void setCallbackDelegate ( DelegateClass* del ) { delegate = del; }

void callbackA ( uint32_t magic )
{
    [delegate handleCallbackA:magic];
}

// and so on...

[Update: as gf points out, you can use a class method and avoid the need for setCallbackDelegate.]

walkytalky