Function pointers as parameters

19 views
Skip to first unread message

Slawomir Czarko

unread,
Mar 26, 2010, 3:28:00 AM3/26/10
to pococapsule
Hi,

I just started evaluating pococapsule for use in a project at work. I
was able to get a simple example running quite quickly. Good job.

Now I'm trying a bit more complex cases. I have a class which has a
constructor taking a function pointer as a parameter. I haven't found
a way to define this in setup.xml file.
Is this supported by pococapsule?

Regards,
Slawomir

Zen

unread,
Mar 26, 2010, 4:00:43 AM3/26/10
to pococ...@googlegroups.com
Hi Slawomir,

I had the same problem and I solved it by:

In C++:
typedef:ed the function prototype.

Created a factory method that returned the wanted function
MyFuncProtoType GetFunctionPointer()
{
return MyFunction;
}

In XML-config file;
created a bean which returned a dereferenced version of the prototype.
<bean id="func" class="*MyFuncProtoType"
function-method="GetFunctionPointer" />

There might be other and better solutions, but that was the strategy I used.

Hope it helps

Regards,
Per B�hlin
Link�ping, Sweden

tom

unread,
Mar 26, 2010, 4:23:52 AM3/26/10
to pococ...@googlegroups.com
Hi,

How do you think to wrap the function pointer in a class, then pass
the class bean to your target class?

Best regards
Tom

On Fri, Mar 26, 2010 at 4:00 PM, Zen <z...@devconsoft.se> wrote:
> Hi Slawomir,
>
> I had the same problem and I solved it by:
>
> In C++:
> typedef:ed the function prototype.
>
> Created a factory method that returned the wanted function
> MyFuncProtoType GetFunctionPointer()
> {
>        return MyFunction;
> }
>
> In XML-config file;
> created a bean which returned a dereferenced version of the prototype.
> <bean id="func" class="*MyFuncProtoType"
>        function-method="GetFunctionPointer" />
>
> There might be other and better solutions, but that was the strategy I used.
>
> Hope it helps
>
> Regards,

> Per Böhlin
> Linköping, Sweden


>
> Slawomir Czarko wrote:
>> Hi,
>>
>> I just started evaluating pococapsule for use in a project at work. I
>> was able to get a simple example running quite quickly. Good job.
>>
>> Now I'm trying a bit more complex cases. I have a class which has a
>> constructor taking a function pointer as a parameter. I haven't found
>> a way to define this in setup.xml file.
>> Is this supported by pococapsule?
>>
>> Regards,
>> Slawomir
>>
>

> --
> You received this message because you are subscribed to the Google Groups "pococapsule" group.
> To post to this group, send email to pococ...@googlegroups.com.
> To unsubscribe from this group, send email to pococapsule...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/pococapsule?hl=en.
>
>

Zen

unread,
Mar 26, 2010, 5:09:36 AM3/26/10
to pococ...@googlegroups.com
Sometimes when working with legacy code and external frameworks you
cannot always control the API:s you program against. So the technique of
passing function pointers is a valid scenario, I think.

In my case I wanted to instantiate a framework that I did not control.
The API of the framework required function pointers so that is what was
used. The API in my case was the HAAF's game engine.

regards,
Per B�hlin

tom wrote:
> Hi,
>
> How do you think to wrap the function pointer in a class, then pass
> the class bean to your target class?
>
> Best regards
> Tom
>
> On Fri, Mar 26, 2010 at 4:00 PM, Zen <z...@devconsoft.se> wrote:
>> Hi Slawomir,
>>
>> I had the same problem and I solved it by:
>>
>> In C++:
>> typedef:ed the function prototype.
>>
>> Created a factory method that returned the wanted function
>> MyFuncProtoType GetFunctionPointer()
>> {
>> return MyFunction;
>> }
>>
>> In XML-config file;
>> created a bean which returned a dereferenced version of the prototype.
>> <bean id="func" class="*MyFuncProtoType"
>> function-method="GetFunctionPointer" />
>>
>> There might be other and better solutions, but that was the strategy I used.
>>
>> Hope it helps
>>
>> Regards,

>> Per B�hlin
>> Link�ping, Sweden

Slawomir Czarko

unread,
Mar 26, 2010, 7:30:08 AM3/26/10
to pococapsule
What I'm trying to do is to have 3 classes:

- EventSource
- EventHandler
- EventDelegator

EventSource provides a way to register callbacks to be executed when
some event happens (the events are received using IPC from another
process)
EventHandler implements the logic of actually processing the events
EventDelegator class is supposed to take care of connecting
EventHandler with EventSource by registering callbacks to EventHandler
methods with EventSource - that's where I want to use the function
pointers:

template < typename Event >
EventDelegator::EventDelegator( EventSource & source, EventHandler &
handler, void (EventHandler::*func)( const Event & ) )
{
source.RegisterHandler( Callback( handler, func ) ); // Callback
object stores the handler and func
}

Then I'd like to instantiate the objects like this:

EventSource source;
EventHandler handler;
EventDelegator< Foo > edFoo( source, handler, &EventHandler::OnFoo );
EventDelegator< Bar > edBar( source, handler, &EventHandler::OnBar );

From what I understood I cannot do this directly in pococapsule, can
I?

I can of course add methods to EventHandler to return Callback objects
but I'd like to avoid that.

Another option is to provide a class or function which would execute
this code directly:

source.RegisterHandler( Callback( handler, &EventHandler::OnFoo ) );
source.RegisterHandler( Callback( handler, &EventHandler::OnBar ) );


Regards,
Slawomir

Ke Jin

unread,
Mar 26, 2010, 12:23:26 PM3/26/10
to pococapsule
It is supported and documented (3.2.1). Also, see the example in Zen's
followup. Thanks Zen and Tom.

Ke

On Mar 26, 12:28 am, Slawomir Czarko <slawomir.cza...@gmail.com>
wrote:

Ke Jin

unread,
Mar 26, 2010, 12:52:05 PM3/26/10
to pococapsule
The issue here is not about

On Mar 26, 4:30 am, Slawomir Czarko <slawomir.cza...@gmail.com> wrote:
> What I'm trying to do is to have 3 classes:
>
> - EventSource
> - EventHandler
> - EventDelegator
>
> EventSource provides a way to register callbacks to be executed when
> some event happens (the events are received using IPC from another
> process)
> EventHandler implements the logic of actually processing the events
> EventDelegator class is supposed to take care of connecting
> EventHandler with EventSource by registering callbacks to EventHandler
> methods with EventSource - that's where I want to use the function
> pointers:
>
> template < typename Event >
> EventDelegator::EventDelegator( EventSource & source, EventHandler &
> handler, void (EventHandler::*func)( const Event & ) )
> {
>   source.RegisterHandler( Callback( handler, func ) ); // Callback
> object stores the handler and func
>
> }
>
> Then I'd like to instantiate the objects like this:
>
> EventSource    source;
> EventHandler   handler;
> EventDelegator< Foo >  edFoo( source, handler, &EventHandler::OnFoo );
> EventDelegator< Bar >  edBar( source, handler, &EventHandler::OnBar );
>

<bean id="source" class="EventSource"/>
<bean id="handler" class="EventHandler"/>
<bean id="on-foo" class="*void (EventHandler::*func)( const Event
& )" factory-method="getOnFoo"/>
<bean id="on-bar" class="*void (EventHandler::*func)( const Event
& )" factory-method="getOnBar"/>

<bean id="foo" class="EventDelegator{Foo}" factory-method="edFoo">
<method-arg ref="source" pass="deref"/>
<method-arg ref="handler" pass="deref/>
<method-arg ref="on-foo"/>
</bean>

Here, the getOnFoo() and getOnBar() are just two inline functions (or
marcos) that return (or are defined as) EventHandler::OnFoo and
EventHandler::OnBar respectively.

Slawomir Czarko

unread,
Mar 26, 2010, 1:32:06 PM3/26/10
to pococapsule

On Mar 26, 5:52 pm, Ke Jin <kjin...@gmail.com> wrote:
>   <bean id="source" class="EventSource"/>
>   <bean id="handler" class="EventHandler"/>
>   <bean id="on-foo" class="*void (EventHandler::*func)( const Event
> & )" factory-method="getOnFoo"/>

this should really be:

class="*void (EventHandler::*func)( const Foo &amp; ) const"

otherwise it doesn't parse as proper XML

Problem is now that the generated C++ code doesn't compile, I get
error on this line:

void (EventHandler::*func)( const Foo & ) const _poco_var_2 =
(void (EventHandler::*func)( const Foo & ) const)(_poco_params[_poco_i+
+]);

which should probably be:

void (EventHandler::*_poco_var_2)( const Foo & ) const = (void
(EventHandler::*)( const Foo & ) const)(_poco_params[_poco_i++]);

but even then the compiler complains about cast from void * to member
function pointer:

setup_reflx.cc:30: error: invalid cast from type 'void*' to type 'void
(EventHandler::*)(const Foo&)const'

Any ideas?

Slawomir Czarko

unread,
Mar 26, 2010, 1:58:58 PM3/26/10
to pococapsule
I got it working after changing member function pointers to non-member
function pointers and using typedef for the function pointer.
Not exactly what I was going for but maybe I can figure something
out :)

Slawomir Czarko

unread,
Mar 26, 2010, 2:33:50 PM3/26/10
to pococapsule
I created a couple of macros to generate automatically required
typedefs and inline static functions within the EventHandler class:

#define EVENT_HANDLER( ClassName, EventName, RealHandler ) \
void RealHandler( const EventName & arg ); \
\
static \
void StaticEventHandlerFor##EventName( ClassName * obj, const
EventName & arg ) \
{ \
obj->RealHandler( arg ); \
} \
\
typedef void (*EventName##EventHandler)( ClassName *, const
EventName & ); \
\
static \
EventName##EventHandler \
Get##EventName##EventHandler() \
{ \
return &ClassName::StaticEventHandlerFor##EventName; \
}

#define EVENT_HANDLER_CONST( ClassName, EventName, RealHandler ) \
void RealHandler( const EventName & arg ) const; \
\
static \
void StaticEventHandlerFor##EventName( const ClassName * obj, const
EventName & arg ) \
{ \
obj->RealHandler( arg ); \
} \
\
typedef void (*EventName##EventHandler)( const ClassName *, const
EventName & ); \
\
static \
EventName##EventHandler \
Get##EventName##EventHandler() \
{ \
return &ClassName::StaticEventHandlerFor##EventName; \
}

I use these macros to declare the event handlers:

class EventHandler
{
public:

EVENT_HANDLER( EventHandler, Boo, HandleBoo );

EVENT_HANDLER_CONST( EventHandler, Foo, HandleFoo );

};

and then I provide the implementation of each handler as usual:

void EventHandler::HandleBoo( const Boo & arg )
{
...
}

void EventHandler::HandleFoo( const Foo & arg ) const
{
...
}

the setup.xml file looks like this:

<bean id="on-boo"
class="*EventHandler::BooEventHandler"
factory-method="EventHandler::GetBooEventHandler"/>

<bean id="ed-boo"
class="EventDelegator">


<method-arg ref="source" pass="deref"/>

<method-arg ref="eh" pass="deref"/>
<method-arg ref="on-boo"/>
</bean>

<bean id="on-foo"
class="*EventHandler::FooEventHandler"
factory-method="EventHandler::GetFooEventHandler"/>

<bean id="ed-foo"
class="EventDelegator">


<method-arg ref="source" pass="deref"/>

<method-arg ref="eh" pass="deref"/>
<method-arg ref="on-foo"/>
</bean>


Thanks for the help!

Slawomir

Ke Jin

unread,
Mar 27, 2010, 12:10:45 AM3/27/10
to pococapsule
On Mar 26, 10:58 am, Slawomir Czarko <slawomir.cza...@gmail.com>
wrote:

Yeap! typedef is always recommended in dealing with function point
types. memory function pointers (not member functions as function
pointers) should also be support. Also, many thanks for posting your
work. Nice investigation!

Ke

Reply all
Reply to author
Forward
0 new messages