Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Pass C# Delegate as Callback to C++

0.00/5 (No votes)
29 May 2012 1  
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#

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:

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

[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)

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

The definition of the same in 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++

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

Acknowledgements

History

  • 29th May, 2012: Tip uploaded

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here