Click here to Skip to main content
15,867,488 members
Articles / Programming Languages / Objective C
Tip/Trick

Handle Managed(C#) Event in Managed(C++/CLI)

Rate me:
Please Sign up or sign in to vote.
4.55/5 (13 votes)
10 Oct 2022CPOL 29K   471   15   1
Handle managed (C#) event in managed (C++/CLI)
In this article I explain how to call event from managed C# application to managed C++/CLI

Introduction

While working with one project, we had a requiremnet in which an event had to be raised from managed application and had to handle that event in managed C++ application. We read many articles and blogs but did not get a proper example. After spending two days, we managed to handle the event in managed C++. So, I added this tip which might help others.

Implementing a Library for Event in C#

As a first step, implement managed library that raises an event.

Create a new C# Class Library project from Visual Studio and add the below code in its class file.

C#
using System;

namespace CSharpWithEvent
{
     /// <summary>
    /// Packet that will be used as part of argument in event.
    /// </summary>
    public class UpdateInfo
    {
        public string PropertyName { get; set; }
        public int NewValue { get; set; }
    }
    /// <summary>
    /// Class derived from EventArgs that is used by our event.
    /// </summary>
    public class ValueChangeEventArgs : EventArgs
    {
        private UpdateInfo _updatePacket;

        public UpdateInfo UpdatePacket
        {
            get { return _updatePacket; }
            set { _updatePacket = value; }
        }
        public ValueChangeEventArgs(UpdateInfo updatePacket)
        {
            _updatePacket = updatePacket;
        }
    }
    /// <summary>
    /// Main class that manages events and objects.
    /// </summary>
    public class ImageManager
    {
        private EventHandler<valuechangeeventargs> _onValueChanged;
        public event EventHandler<valuechangeeventargs> OnValueChanged
        {
            add { _onValueChanged += value; }
            remove { _onValueChanged -= value; }
        }

        /// <summary>
        /// Method that is called to update Image.
        /// <summary>
        public void UpdateImage(UpdateInfo updatePacket)
        {
            /*Raised Event*/
            if (_onValueChanged != null)
            {
                _onValueChanged(this, new ValueChangeEventArgs(updatePacket));
            }
        }
        /// <summary>
        /// A method to raise an event from user code itself.
        /// <summary>
        public void RaiseUpdateEvent()
        {
            UpdateInfo updatePacket = new UpdateInfo();
            UpdateImage(updatePacket);
        }
    }
}

Implementing Client/User Application in Managed C++

This is the C++ project that we need to handle event that will be raised from the above C# project.

  1. Create a new C++/CLI CLR Console Application.
  2. To handle an event in native class, we need to write managed wrapper/helper class that will intercept the event and redirect to native object, so here is the simple helper class written in managed C++.
    C++
    //Helper.h
    
    #include "stdafx.h"
    #include <vcclr.h>
    #include "ImageUserClass.h"
    using namespace System;
    
    ref class Helper
    {
    public:
    	Helper();
        ImageUserClass* mPtr;
        void OnImageValueChange( Object^ sender, ValueChangeEventArgs^ updatePacket );
    };
    
    //Helper.cpp
    
    #include "stdafx.h";
    #include "Helper.h"
    #include "ImageUserClass.h"
    
    Helper::Helper()
    {
    	
    }
    void Helper::OnImageValueChange( Object^ sender, ValueChangeEventArgs^ updatePacket )
    {
        mPtr->OnImageValueChange( sender, updatePacket );
    }
  3. At last, we only need a native C++ class which implements event handler. Below is the code for the same.
    C++
    //ImageUserClass.h
    #pragma once
    #include "stdafx.h"
    #include <vcclr.h>
    using namespace std;
    using namespace System;
    using namespace CSharpWithEvent;
    
    class ImageUserClass
    {
    public:
    	gcroot<imagemanager^> m_imageManager;
    	ImageUserClass();
    	void OnImageValueChange(Object^ sender, ValueChangeEventArgs^ updatePacket);
    };
    
    //ImageUserClass.cpp
    
    #include "stdafx.h";
    #include "Helper.h";
    using namespace std;
    using namespace System;
    ImageUserClass::ImageUserClass()
    {
    	Helper^ h = gcnew Helper;
    	h->mPtr = this;
    	m_imageManager = gcnew ImageManager();
    	m_imageManager->OnValueChanged += gcnew EventHandler<valuechangeeventargs^>
                                                 (h, &Helper::OnImageValueChange );
    	<valuechangeeventargs^>m_imageManager->RaiseUpdateEvent();
    }
    void ImageUserClass::OnImageValueChange(Object^ sender, ValueChangeEventArgs^ updatePacket)
    {
    	Console::WriteLine("Update packet received.");
    }

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) The Beast Apps
India India
Working with C++/VC++ in windows based application. He works as a Senior Software Engineer for The Beast Apps in finance domain. He has worked for Kongsberg Maritime in Automation domain for 6 years.

Comments and Discussions

 
QuestionAlternative approach Pin
hofingerandi8-Mar-15 23:53
hofingerandi8-Mar-15 23:53 
An alternative approach that avoids implementing helper classes is shown in Demo5 this aricle C++/CLI Library classes for interop scenarios[^]

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.