boost::shared_ptr

mwilsonmwilson Member Mark WilsonOrganization: Integrated Computer Solutions, Inc.Project: TBD ✭✭✭
I want to create a Boost function object by binding to an Ice proxy member function:


boost::bind(&IceProxy::DVAC::DVACControl::setTransSetpoint, thePrx, _1);


Unfortunately, this doesn't work. Bind is looking for a get_pointer function to return an actual pointer for the binding. So, instead, I need to do this:

boost::bind(&IceProxy::DVAC::DVACControl::setTransSetpoint, thePrx.get(), _1);

Correct me if I am wrong, but this means that the reference count for the proxy handle will not be incremented, which leaves the program open to a null pointer error.

Any advice on what to do?

Comments

  • bernardbernard Jupiter, FLAdministrators, ZeroC Staff Bernard NormierOrganization: ZeroC, Inc.Project: Ice ZeroC Staff
    Hi Mark,

    I am not sure what "SetPoint" represents in your expression.

    get() on a Proxy handle (Prx object) will indeed extract the underlying pointer without incrementing the reference count of the target proxy object. As long as you use this pointer while you hold the associated Prx object (and nobody changes this Prx), I don't see any risk.

    Cheers,
    Bernard
  • mwilsonmwilson Member Mark WilsonOrganization: Integrated Computer Solutions, Inc.Project: TBD ✭✭✭
    Should have been "setTransSetpoint", which is the function on the proxy I want to bind to.
  • mwilsonmwilson Member Mark WilsonOrganization: Integrated Computer Solutions, Inc.Project: TBD ✭✭✭
    Finally got back to this and figured it out; you need to define get_pointer for whatever smart pointer/handle is being used, in this case IceInternal::ProxyHandle, and it has to be in the proper namespace:
    namespace IceProxy
    {
    namespace DVAC
    {
        template<class T> inline T* get_pointer(
            IceInternal::ProxyHandle<T> const & p)
        {
            return p.get();
        }
    }
    }
    

    Now I can create boost function objects via boost::bind that will maintain the reference count for an Ice proxy.

    So for an interface:
    module A
    {
         interface B
         {
             void function1(int i);
         };
    };
    

    I can do
    class Contrived
    {
    public:
        void setFunctionToCall(const boost::function<void(int)> & func)
        {
            func_ = func;
        }
    
        void doSomething(int i)
        {
             func_(i); // calls onto proxy.
        }
    private:
        boost::function<void(int)> func_;
    };
    
    .
    .
    .
    A::BPrx theProxy;
    
    boost::function<void(int)> f = boost::bind(&IceProxy::A::B::function, theProxy, _1);
    
    Contrived c;
    c.setFunctionToCall(f);
    
    c.doSomething(23);
    
    

    As long as the c object doesn't go out of scope, the proxy will not be deleted.
  • mwilsonmwilson Member Mark WilsonOrganization: Integrated Computer Solutions, Inc.Project: TBD ✭✭✭
    In
    boost::function<void(int)> f = boost::bind(&IceProxy::A::B::function, theProxy, _1);
    

    &IceProxy::A::B::function should be &IceProxy::A::B::function1
Sign In or Register to comment.