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






4.55/5 (13 votes)
Handle managed (C#) event in 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.
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.
- Create a new C++/CLI CLR Console Application.
- 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++.
//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 ); }
- At last, we only need a native C++ class which implements event handler. Below is the code for the same.
//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."); }