Introduction
Is it possible?
Yes, it is absolutely possible, but you have to remember one thing. You can�t call a .NET function from a Win32 Process. It is ever never possible until you externally load the CLR. So, in this article, we are going to see how to call a .NET function from a Windows Custom DLL (for example, a DLL written in VC++), within a .NET process.
Is it needful?
Yes, it will be needful. Developers who are working in Win32 API from .NET, some time requires notification from unmanaged code to a managed function in .NET environment (for example, to notify completion of an asynchronous call). At that time, they can use this methodology to complete their task.
Is the Example given useful?
No, we take this code example for demonstration purpose only. In this example, we are going to call an unmanaged code from managed code, and the unmanaged code itself again calls another managed code (you can use this technique to notify the .NET environment about an asynchronous event from unmanaged code).
Basic Idea
Usually, we can call a function through two methods. The first one is using function name, and the next one is through the function pointer. Here, we are going to call a function from another (unmanaged) environment, so we can�t use the function name directly, so we are going to use function pointer. The first step is, we have to give the function pointer to unmanaged code, and then the unmanaged code will use this function pointer to call the managed code.
The core thing is described in the following figure:
For checking that, we will create one custom DLL in VC++, and implement two functions. One is SetCallBackPointer
, which receives a function pointer from managed code and stores it in a global variable pFunction
. Another function InvokeCallBack
is to call the managed code using function pointer pFunction
. Here is the code residing in the DLL source file.
typedef VOID (*CALLBACK_FUNCTION )();
CALLBACK_FUNCTION pFunction;
void SetCallBackPointer(LPVOID FnAddress);
void InvokeCallBack();
void SetCallBackPointer(LPVOID FnAddress)
{
pFunction = (CALLBACK_FUNCTION)FnAddress;
InvokeCallBack();
}
void InvokeCallBack()
{
(pFunction)();
}
Then we have to export the SetCallBackPointer
to make it callable from out of the DLL.
LIBRARY MYCUSTOMDLL
EXPORTS
SetCallBackPointer
OK, now we can build our DLL and create MyCustomDll.dll. Next, we are going to write the C# code for the callback function:
public static void CallbackFunction()
{
MessageBox.Show( �CallBack Function Called by Windows DLL�);
}
We can�t directly give the function name as the function pointer as we do it in C, C++ or VC++. Fortunately, we can do that using delegates. (I hope that you are all familiar, with one of .NET�s wonderful future: delegates. If you are not familiar with delegates, please refer MSDN.)
Let�s declare a delegate and instantiate it as follows.
delegate void CallBackDelegate();
public static CallBackDelegate myDelegate;
Next, we have to associate our callback function with the delegate:
myDelegate =new MyDelegate(CallbackFunction);
OK, now our function pointer is ready. Next step is, we have to send it to the DLL. To render the callback function (that is delegate) to DLL, we have to call SetCallBackPointer
function in the custom DLL. For that, we have to declare a function prototype of SetCallBackPointer
with DllImport
attribute. Here is the declaration:
[DllImport("MyCustomDll.dll",CallingConvention=CallingConvention.StdCall)]
private static extern void SetCallBackPointer(CallBackDelegate delegate);
Everything is ready now; remaining is, we have to call SetCallBackPointer
function. The following call will invoke the SetCallBackPointer
function in the MyCustomDll with CallBackFunction
function pointer (delegate) as the argument:
SetCallBackPointer(myDelegate);
Yes we got it, CallBackFunction
is called from our custom DLL.