Click here to Skip to main content
Click here to Skip to main content

Tagged as

Pass C# Delegate as Callback to C++

, 29 May 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Mukit, Ataul
Chief Technology Officer Rational Technologies
Bangladesh Bangladesh
C++ is not C with classes, JQuery is not Javascript, Google Search is not Learning, Design Patterns are not fashion, A code written in 2005 is not backdated just because it's 2015
Follow on   Twitter

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.1411028.1 | Last Updated 29 May 2012
Article Copyright 2012 by Mukit, Ataul
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid