C++/CLI - Managed class to C# events

前端 未结 3 1940
别跟我提以往
别跟我提以往 2021-01-21 20:31

I have a c++ class that triggers some method like an event.

class Blah {

   virtual void Event(EventArgs e);
}

How can I wrap it so whenever t

3条回答
  •  灰色年华
    2021-01-21 21:12

    You need to do some work to reflect the Event() method call so it can be hooked by a managed class. Lets implement a concrete blah class that does so:

    #pragma managed(push, off)
    
    struct EvenAtrgs {};
    
    class blah {
    public:
       virtual void Event (EvenAtrgs e) = 0;
    };
    
    typedef void (* CallBack)(EvenAtrgs);
    
    class blahImpl : blah {
        CallBack callback;
    public:
        blahImpl(CallBack fp) {
            this->callback = fp;
        }
        virtual void Event(EvenAtrgs e) { 
            callback(e); 
        }
    };
    #pragma managed(pop)
    

    You can now construct a blahImpl and pass it a function pointer that is called when the Event() method is called. You can use Marshal::GetFunctionPointerForDelegate() to get such a function pointer, it creates a stub for a delegate that makes the transition from unmanaged code to managed code and can store a instance as well. Combined with the boilerplate code to wrap an unmanaged class:

    public ref class blahWrapper {
        blahImpl* instance;
        delegate void managedCallback(EvenAtrgs e);
        managedCallback^ callback;
        void fireEvent(EvenAtrgs e) {
            // Todo: convert e to a managed EventArgs derived class
            //...
            Event(this, EventArgs::Empty);
        }
    public:
        event EventHandler^ Event;
        blahWrapper() {
            callback = gcnew managedCallback(this, &blahWrapper::fireEvent);
            instance = new blahImpl((CallBack)(void*)System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(callback));
        }
        ~blahWrapper() { delete instance; }
        !blahWrapper() { delete instance; }
    };
    

    The C# code can now write an event handler for the Event event. I left the spelling error in tact, you need to do some work to convert EvenAtrgs to a managed class that derives from EventArgs. Modify the managed Event accordingly.

提交回复
热议问题