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.
using System;
namespace CSharpWithEvent
{
public class UpdateInfo
{
public string PropertyName { get; set; }
public int NewValue { get; set; }
}
public class ValueChangeEventArgs : EventArgs
{
private UpdateInfo _updatePacket;
public UpdateInfo UpdatePacket
{
get { return _updatePacket; }
set { _updatePacket = value; }
}
public ValueChangeEventArgs(UpdateInfo updatePacket)
{
_updatePacket = updatePacket;
}
}
public class ImageManager
{
private EventHandler<valuechangeeventargs> _onValueChanged;
public event EventHandler<valuechangeeventargs> OnValueChanged
{
add { _onValueChanged += value; }
remove { _onValueChanged -= value; }
}
public void UpdateImage(UpdateInfo updatePacket)
{
if (_onValueChanged != null)
{
_onValueChanged(this, new ValueChangeEventArgs(updatePacket));
}
}
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++.
#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 );
};
#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.
#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);
};
#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.");
}