WIP and C++

Hi

Any ideas on how to use the WIP library with C++ ??

extern "C"
 {
	#include "adl_global.h"
	#include "wip.h"
class myClass
{
    public:
void thing(void){
  int a =WIP_CEV_OPEN;   //Problem description: Symbol 'WIP_CEV_OPEN' could not be  resolved
}
private:
}

Seems to be related to the fact that WIP_CEV_OPEN enum definition is enclosed in wip_event_t structure definition (cf. wip_channel.h)
To use this constant in C++, you’ll need to reference it as:

int a = wip_event_t::WIP_CEV_OPEN

Yes thanks - you are correct.

I hadn’t thought of that and had, as a temporary workaround, redefined the events again as a typedef enum which was not a good way

Hi

Then I got stuck again - how do we bind the callbacks - my attempt below isn’t correct :frowning:

Thanks in advance

Ted

class udpClass
{
    public:

	udpClass ( void );	
	void udp_start(u32 updPort);

    private:

	// Callback pointers
	static void udp_event_cbh(wip_event_t *event, void* ctx);	// Channel (socket) callback handler
};

void udpClass::udp_event_cbh(wip_event_t *event, void* ctx)
{}

udp_state_t udpClass::udp_start(u32 updPort){
       udpChannel=wip_UDPCreateOpts(&udpClass::udp_event_cbh, NULL,WIP_COPT_PORT, updPort,WIP_COPT_END);
}

As ADL or WIP are written in C, you have to provide C callbacks… AFAIK there is no way to provide class methods (even static ones) as callbacks to a C API…
You’ll have to implement the callback in an extern “C” block of a cpp file.

Hi Daav

Thanks for the information - as you can probably tell I’m not used to mixing C and C++.

I now understand - I think this C++ limitation means that it’s impossible to build a proper class which wrappers C which uses callbacks.

Shame - I was hoping to save a lot of time by creating a C++ WIP interface to enable many identical socket objects - never mind I’ll have to go back to the old C way

Ted

I think that you can do it anyhow: most (and even maybe all) of the WIP callbacks can bear an opaque “context” pointer.
You should be able to use one single generic C callback for all your instances, and use the context pointer to carry your current object instance.

Hi Daav

Thanks - yes from a C perspective the context method works well.

I don’t think a WIP context could point to a C++ class member - I’m not sure of any other methods I could use to connect a WIP context to a C++ class member

It works - you just need static casts.

Here’s how we do it, in this case with a timer callback that uses a similar API:

extern "C"
{
static void FooBarTimerWrapper(u8 ID, void * Context)
{
    Foo* fooInstance = static_cast<Foo*>(Context);
    fooInstance->Bar();
}
}

Which gets set up from inside of a Foo instance like this:

void Foo::TriggerTimerCallback(int delay)
{
    adl_tmrSubscribeExt(ADL_TMR_CYCLIC_OPT_NONE, delay, ADL_TMR_TYPE_TICK, FooBarTimerWrapper, this, false);
}

Hiya,

Just be aware that with timer contexts that if you cancel the timer (and thus don’t call the handler), there is no way to free the context if you don’t keep another link to it somewhere (which in my view sort of defeats the purpose of a context pointer) - so you will get a memory leak.

It would be nice if there was some sort of timer finalizer that could be called if the timer was cancelled…

ciao, Dave