
I have a class, where I want callers to be able to register/deregister signals/slots. They will pass in a function pointer, and we'll hook it up to the signal, and manage the connection object. Part of the management, is I need to map the function pointer to the actual connection object. This is where the trouble comes in. Since a boost::function doesn't have an operator <, the simplest way is to just map it to an unsigned long long, and store the raw address of the underlying function. So, my connect function: typedef VSSP (*TargetType) ( std::string, EncodingEnum); typedef boost::function < VSSP ( std::string, EncodingEnum) > CreateTypeFunc; bool ElementBase::connectCreateTypeSignal(const CreateTypeFunc& slot) { LOG4CXX_DEBUG(logger_, "connectCreateTypeSignal in"); bool retValue = false; unsigned long long slotAddr = (unsigned long long)slot.target< TargetType >(); LOG4CXX_DEBUG(logger_, "*** slotAddr = " + (boost::format("%08X") % slotAddr).str()); <snip> } One of my checks, is to ensure that you don't connect the same thing multiple times. So, I have a test case that does this, and expects it to bomb out: VSSP getTypeSlot(std::string fqn, EncodingEnum encoding) { <snip> return VSSP; } BOOST_FIXTURE_TEST_CASE(ElementBase_connectCreateType, ElementBaseTestFixture) { BOOST_CHECK(true == ebp->connectCreateTypeSignal(getTypeSlot)); BOOST_CHECK(false == ebp->connectCreateTypeSignal(getTypeSlot)); } My debug printouts, are shoing unexpected behavior. The address that I am getting from target is different every time it is called, even though I'm calling with the same function (getTypeSlot). I would expect this if I was getting the address of the function object, because I'm creating one implicitly through the call, but not dereferencing via target(), unless I'm misunderstanding what target() does. I just need the stupid address of the function passed in. Help!! TIA --dw

AMDG david.weber@l-3com.com wrote:
I have a class, where I want callers to be able to register/deregister signals/slots. They will pass in a function pointer, and we'll hook it up to the signal, and manage the connection object.
Part of the management, is I need to map the function pointer to the actual connection object. This is where the trouble comes in. Since a boost::function doesn't have an operator <, the simplest way is to just map it to an unsigned long long, and store the raw address of the underlying function.
So, my connect function:
typedef VSSP (*TargetType) ( std::string, EncodingEnum); typedef boost::function < VSSP ( std::string, EncodingEnum) > CreateTypeFunc;
bool ElementBase::connectCreateTypeSignal(const CreateTypeFunc& slot) { LOG4CXX_DEBUG(logger_, "connectCreateTypeSignal in"); bool retValue = false;
unsigned long long slotAddr = (unsigned long long)slot.target< TargetType >(); LOG4CXX_DEBUG(logger_, "*** slotAddr = " + (boost::format("%08X") % slotAddr).str());
<snip> }
My debug printouts, are shoing unexpected behavior. The address that I am getting from target is different every time it is called, even though I'm calling with the same function (getTypeSlot). I would expect this if I was getting the address of the function object, because I'm creating one implicitly through the call, but not dereferencing via target(), unless I'm misunderstanding what target() does.
target returns a pointer to the function object. If TargetType is void(*)() target will return an object of type void(**)(). In Christ, Steven Watanabe

<snip>
target returns a pointer to the function object. If TargetType is void(*)() target will return an object of type void(**)().
So, I modfied my function to:
unsigned long long slotAddr = (unsigned long long)slot.target<
void(*)() >();
LOG4CXX_DEBUG(logger_, "*** slotAddr = " + (boost::format("%016X") %
slotAddr).str());
But my prints of the value show:
connectCreateTypeSignal in
*** slotAddr = 0000000000000000
Looking at the debugger, it's setting the results to zero in
function_base.hpp, line 537, when it makes the call to vtable->manager.
This is dying down in function_base.hpp(284) where this code is run:
const BOOST_FUNCTION_STD_NS::type_info& check_type =
*static_cast

AMDG david.weber@l-3com.com wrote:
<snip>
target returns a pointer to the function object. If TargetType is void(*)() target will return an object of type void(**)().
So, I modfied my function to:
unsigned long long slotAddr = (unsigned long long)slot.target< void(*)() >(); LOG4CXX_DEBUG(logger_, "*** slotAddr = " + (boost::format("%016X") % slotAddr).str());
Sorry, I was unclear. void(*)() was just intended as an illustration of what happens to function pointers when you call target. Try dereferencing the result of target. const TargetType* target = slot.target<TargetType>(); (unsigned long long)(*target); In Christ, Steven Watanabe

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On Wednesday 10 December 2008 14:45 pm, david.weber@l-3com.com wrote:
Part of the management, is I need to map the function pointer to the actual connection object.
I'm curious to hear more about your use case. The signal class supports disconnect-by-slot, did you need the connection object for something other than just disconnecting? It would seem possible to generalize disconnect-by-slot into a more general method which returns a list of connections whose slot or group is equal to the method's argument. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) iD8DBQFJQCry5vihyNWuA4URAhFtAKDQpxYlM4YEC6JyJ11wNgDH7ggtrgCgtPnh fX5tzx2Q9v11fm04RPZbXBo= =Viis -----END PGP SIGNATURE-----

I suppose that it's good to back up a bit, and discuss that to make sure I'm at least on the right track. I have an object which will signal when something interesting occurs. (Signaller) I want other "interested" objects to receive this signal when that "interesting thing" occurs. (Slotter) We wanted to encapsulate the signal.connect(&slot) calls within the Signaller and then the Slotter just hooks up whatever function they want (provided it matches the function signature). Now, the slots are most likely going to be instance member functions, which according to my research, and my own testing, is easiest done with boost::bind. So, the Signaller has a connect(&slot) function, that returns success or not. It didn't seem "natural" for the Slotter to have to keep & maintain his connection object for eventual disconnection of the signal. So a disconnect(&slot) function was added to the Signaller class. We want to be as robust as possible, and our use case doesn't allow the same slot to be connected to a signal multiple times, so this (and several other reasons) are why we are looking at maintaining this stl map separately. I'm going from memory at this point, but I believe the reason we call connection.disconnect() versus signal.disconnect(&slot), is in our Signaller.disconnect(&slot), the Slotter didn't necessarily maintain their own bind object permanently. For simple cases, you don't even need the bind object at all. If I go from memory, it was creating a new bind object every single time, and you couldn't disconnect properly. Let me dig up that code again, see if I can remember why I decided to go this route. It's obviously a bit complicated, and I would love to alleviate the connection management from the Signaller class alltogether. --dw
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Frank Mori Hess Sent: Wednesday, December 10, 2008 2:48 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] signals/slots and boost::functions
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Part of the management, is I need to map the function
On Wednesday 10 December 2008 14:45 pm, david.weber@l-3com.com wrote: pointer to the
actual connection object.
I'm curious to hear more about your use case. The signal class supports disconnect-by-slot, did you need the connection object for something other than just disconnecting? It would seem possible to generalize disconnect-by-slot into a more general method which returns a list of connections whose slot or group is equal to the method's argument. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFJQCry5vihyNWuA4URAhFtAKDQpxYlM4YEC6JyJ11wNgDH7ggtrgCgtPnh fX5tzx2Q9v11fm04RPZbXBo= =Viis -----END PGP SIGNATURE----- _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (3)
-
david.weber@l-3com.com
-
Frank Mori Hess
-
Steven Watanabe