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

Pass C# Delegate as Callback to C++

Rate me:
Please Sign up or sign in to vote.
4.91/5 (7 votes)
29 May 2012CPOL1 min read 43.5K   16  
This tip shows how to pass a delegate to a C++ exported DLL function from C#

Introduction

This tip mainly shows how to pass a C# delegate to C++ with the aid of exported DLL functions.

The C++ version of the callback (which is a delegate in C#)

typedef void (__stdcall *fnNotify)(int notifyCode, NotifyStruct* notifyInfo);

How the delegate signature looks like in C#

C#
public delegate void 
DelegateNotify(int notifyCode, ref DLLLoader.NotifyStruct notifyInfo); 

As you should be already aware, you have to instantiate the delegate by code which looks something like this:

C++
new DelegateNotify(fnNotify); // where fnNotify is a method 
		//which exactly has the same signature as the delegate

Let's take a look at the function that would be accepting the callback..

The C++ exported DLL function which takes the callback as argument

extern "C" DLL_IMPORTEXPORT void SetNotifyCallBack(fnNotify callBack);

The C# version of the imported C++ function

C#
[DllImport("TestDLL.dll", CharSet = CharSet.Auto)] 
public static extern void SetNotifyCallBack(MulticastDelegate callback); 

The above definition is inside a DLLLoader class.

Note the MulticaseDelegate argument type which actually does the trick of converting a delegate to a passable C++ callback.

Points of Interest

In the above C++ exported function, the callback takes a simple structure which contains notification data. So this tip also shows a way to marshall simple structures from C++ to C# through the callback function. So here is a little about marshalling simple structures to and fro C# and C++).

The structure to be marshalled (C# version)

C#
public class DLLLoader
{ 
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct NotifyStruct
{
public int notifyHeader; 
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string notifyDescription; 
}
//...
C#
[DllImport("TestDLL.dll", CharSet = CharSet.Auto)] 
public static extern void SetNotifyCallBack(MulticastDelegate callback); 
} 

The definition of the same in C++

C++
typedef struct _tagNotifyStruct
{
  int notifyHeader;
wchar_t notifyDescription[NGH_EXPLORERITEM_MAXLEN]; 

}NotifyStruct;

Now we have defined the structure which is consistent both in C++ and C# (they have to be consistent of course, otherwise they won't work), let's turn our attention to the real thing... passing the Callback (delegate in C#).. to C++

Finally .. Create Delegate and Pass to C++

C#
DelegateNotify callback = new DelegateNotify(fnNotify);
DLLLoader.SetCallBack(callback);

Acknowledgements

History

  • 29th May, 2012: Tip uploaded

License

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


Written By
Technical Lead Kotha Technologies
Bangladesh Bangladesh
If you are not in - you are out !
- Chapter 1

Comments and Discussions

 
-- There are no messages in this forum --