Search code examples
c++c++-clinativefunction-pointersboost-signals

Pass unmanaged member function pointer to be used by wrapper to connect it to the signal in c++/cli


I have implemented the Event Handling with Boost::Signal and Boost::Bind in my managed C++ file. Refered the Link:Boost::bind

Also I have created the function pointer in my native C++ file which is passed to my boost::Signal.Connect() as EventHandler in managed code. The code for function which is passed as function pointer in my Native C++

std::string NativeCplus::AddFunctionPointer( std::string message )  
{
return message;
}

and above function passed as boost::function object in another function NameChangeEvent() as below:

void NativeCplus::NameChangeEvent()
{
UnmanagedNameEvent* unmanagedNameEvent=new UnmanagedNameEvent();
boost::function<std::string (std::string)> f;
f=std::bind1st(std::mem_fun(&AlgebraAPI::AddFunctionPointer),this);//FunctionPointer

std::string name="abcd";
unmanagedNameEvent->AddEvent(f,name);
}

In the above code ,I have taken the boost::function and the function pointer is converted to that boost::function (f).(AM I RIGHT IN SAYING THIS?).Then the line unmanagedNameEvent->AddEvent(f,name) where boost::function(f) is passed to AddEvent(f,name) and this AddEvent(f,name) is implemented in my managed C++ code file. Below is my managed C++ Code which is being referred in the native c++ project:

//In my c++/CLI Wrapper.cpp

    declspec(dllexport) void UnmanagedNameEvent::AddEvent(boost::function<std::string (std::string)> f,std::string name)
        {

                UnmanagedNameEvent* unmanagedNameEvent=new UnmanagedNameEvent();
            unmanagedNameEvent->signalEventMessage.connect(f);
//which should be like this.. unmanagedNameEvent->signalEventMessage.connect(bind(NativeCplus::f));

        }

PROBLEM is I can't use the NativeCplus class to refer to its unmanaged function (i.e.f)as that will create a round dependency of dll file.Any workaround for this?All ears for any shorter solution!!


Solution

  • Here is a sample of what I understand you want:

    Your C++/CLI "wrapper":

    Market.h:

    #include <boost/function.hpp>
    #include <boost/signals2.hpp>
    
    class __declspec(dllexport) Market
    {
        private: boost::signals2::signal<void(double)> signalEvent;
        public: void AddHandler(boost::function<void(double)> handler);
        public: void Move(double value);
    };
    

    Market.cpp:

    #include "Market.h"
    
    #include <boost/function.hpp>
    
    void Market::AddHandler(boost::function<void(double)> handler)
    {
        signalEvent.connect(handler);
    }
    
    void Market::Move(double value)
    {
        signalEvent(value);
    }
    

    And your native app, test.cpp:

    #include <iostream>
    
    #include <boost/function.hpp>
    #include <boost/bind.hpp>
    
    #include "Market.h"
    
    class Investor
    {
        public: void move_handler(double value)
        {
            std::cout << (value >= 0 ? "Hey! I'm the best!" : "Wat! I'm losing my shirt! ") << std::endl;
        }
    };
    
    int main()
    {
        Investor investor;
    
        Market market;
    
        boost::function<void(double)> move = boost::bind(&Investor::move_handler, &investor, _1);
    
        market.AddHandler(move);
    
        market.Move(+0.10);
        market.Move(-0.10);
    }
    

    Results:

    Hey! I'm the best!
    Wat! I'm losing my shirt!
    

    Hope this helps...