C++ C++ C# C# ASP.NET Security ASP.NET Security ASM ASM Скачать Скачать Поиск Поиск Хостинг Хостинг  
  Программа для работы с LPT портом...
Язык: .NET — ©Alexey...
  "ASP.NET Atlas" – AJAX в исполнении Micro...
Язык: .NET — ©legigor@mail.ru...
  "Невытесняющая" Многопоточность...
Язык: C/C++ — ©...
  01.05.2010 — Update World C++: Сборник GPL QT исходников
  15.12.2007 — Весь сайт целиком можно загрузить по ссылкам из раздела Скачать
Хостинг:
Windows 2003, ASP.NET 2.0
бесплатный и от 80 руб./мес


   Отправить письмо
Кулабухов Артем, Беларусь



 Calling Managed .NET Function from Unmanaged Windows Custom DLL. / PInvoke / C#

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.

// MyCustomDll.cpp
//Global Variable for store the function pointer.
 
typedef VOID (*CALLBACK_FUNCTION )();
CALLBACK_FUNCTION pFunction;
 
void SetCallBackPointer(LPVOID FnAddress);
void InvokeCallBack();
 
 
//This function receive the address of the CallBack function as
//parameter and store it in a global variable to enable other function in 
// the DLL to call the CallBack Function.
 
void SetCallBackPointer(LPVOID FnAddress)
{
      pFunction = (CALLBACK_FUNCTION)FnAddress;
// For demonstration purpose only. In real World we may call 
// this function in response to a asynchronous message.
      InvokeCallBack();
}
 
// this function will Invoke the callback function 
// through the function pointer.
void InvokeCallBack()
{
     (pFunction)(); // simply calls the Callback function through pointer.
}

Then we have to export the SetCallBackPointer to make it callable from out of the DLL.

// MyCustomDll.def
//
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:

//       Managed.cs 
//
 
//  Our Callback function which will be called by unmanaged code(Form windows dll).
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.

// Declaring Delegate for Callback Function
// note that the Delegate prototype and Callback function 
// prototype are same.
 
delegate void CallBackDelegate();
public static  CallBackDelegate myDelegate;

Next, we have to associate our callback function with the delegate:

// Associating callback function with 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:

// this function prototype should match our Custom dll’s 
// ‘SetCallBackPointer’ functioin prototype.
//
[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.