Interoperability Series Article :
- . Net short talk about interoperability (1: Introduction At the beginning)
- . Net short talk about interoperability (2: Faster first)
- . Net short talk about interoperability (3: Basic knowledge of dllimport features)
- . Net short talk about interoperability (4: Basic knowledge-based dispose unmanaged memory)
- . Net short talk about interoperability (5: Basic knowledge-based dynamic platform call)
- . Net short talk about interoperability (6: Improving platform calling performance based on basic knowledge)
- . Net short talk about interoperability (7: Introduction to data sending)
We continue to learn about. Net interoperability. In the previous article, we learned about the managed and unmanaged memory dispose (release) issue. Next we will continue to learn the dynamic (dynamic) platform calling Technology in the basic knowledge;
In the previous articles, we used a step-by-step method to call unmanagedCodeFirst, define the managed definition of the unmanaged code, and then use dllimport to identify the relevant call conventions. This article will introduce how to call the unmanaged code dynamically; before explaining it, we need to take a simple look at the steps or details of hosting code calling unmanaged code. Only when we have a set of our own understanding ideas in our mind, the value of the article is obvious;[Wang qingpei has all rights reserved. For more information, please sign it.]
Platform call Process Principle
Text is not expressive. Let's look at the figure;
Figure 1:
This picture is not very full, but it can probably express its meaning;
When we call an unmanaged DLL file for the first time (interspersed here, it involves why some things must be handled by the operating system, why is there a kernel, it is used to process something that we can't do at ordinary times. For the loadlibrary method, it may be that it enters the kernel and then sets relevant parameters, helped us save the agent stubs of the unmanaged DLL in the memory. When we enter the kernel again next time, the system checks and finds that there was a call, so next time you read the address in the stub for calling), the system will load the unmanaged DLL file to the memory and set the relevant data for later use; the principle of dynamic calling is to manually do this part of work. For example, the first call of an unmanaged DLL must be slower than the subsequent call. Therefore, in some necessary scenarios, we really need to perform dynamic P/invoke;
Dynamic platform call Example 1
In managed. net, we can manually load the unmanaged DLL to the memory by using the loadlibrary method in WIN32API;
[Dllimport ("kernel32.dll", entrypoint = "loadlibrary")]
Public static extern intptr loadlibrary (string iplibfilenmae );
Such an operation is like the operation to be executed during the first call in Figure 1;
[Dllimport ("win32dll. dll", entrypoint = "add", charset = charset. Auto, callingconvention = callingconvention. stdcall)]
Private Static extern int add (int x, int y );
Similarly, we declare the definition of the unmanaged code. Let's look at all the code;
Namespace CSHARP. InterOP
{
/// <Summary>
/// Call the dynamic platform and manually load the unmanaged DLL file
/// </Summary>
Public static class dynamicpinvoke
{
[Dllimport ("kernel32.dll", entrypoint = "loadlibrary")]
Public static extern intptr loadlibrary (string iplibfilenmae );
[Dllimport ("win32dll. dll", entrypoint = "add", charset = charset. Auto, callingconvention = callingconvention. stdcall)]
Private Static extern int add (int x, int y );
Public static void test ()
{
String currentdirectory = path. getdirectoryname (assembly. getexecutingassembly (). Location );
String dllpath = path. Combine (currentdirectory, "win32dll. dll ");
Intptr dlladdr = loadlibrary (dllpath );
If (dlladdr = intptr. Zero)
Throw new dllnotfoundexception (string. Format ("the DLL file cannot be found at {0}", dllpath ));
Int addnumber = add (10, 20 );
Console. Write (addnumber );
}
}
}
Dynamic platform call Example 2
In the first example, we omit the system call process and manually call loadlibrary for loading. There may be no major changes. Example 2 uses an unmanaged function delegate for dynamic calling;
All know that hosting a delegate is like an unmanaged function pointer. Fortunately, Microsoft has provided us with a delegate to call an unmanaged method, which is very powerful. Please refer to the code;
[Unmanagedfunctionpointer (callingconvention. stdcall)][Wang qingpei has all rights reserved. For more information, please sign it.]
Delegate int add (int x, int y );
The system features can change the code compilation behavior, so we have reason to believe that our add delegate has become a reference to unmanaged code;
Namespace CSHARP. InterOP
{
[Unmanagedfunctionpointer (callingconvention. stdcall)]
Delegate int add (int x, int y );
Public static class delegateinvoke
{
Public static void test ()
{
String currentdirectory = path. getdirectoryname (assembly. getexecutingassembly (). Location );
String dllpath = path. Combine (currentdirectory, "win32dll. dll ");
Intptr dlladdr = InterOP. dynamicpinvoke. loadlibrary (dllpath );
If (dlladdr = intptr. Zero)
Throw new dllnotfoundexception (string. Format ("the DLL file cannot be found at {0}", dllpath ));
Intptr procadd = WIN32API. getprocaddress (dlladdr, "_ add @ 8 ");
If (procadd = intptr. Zero)
Throw new dllnotfoundexception (string. Format ("{0} entry point not found in memory", Marshal. ptrtostringuni (dlladdr )));
Add adddelegate = (ADD) Marshal. getdelegateforfunctionpointer (procadd, typeof (ADD ));
Int result = adddelegate (10, 20 );
Bool isfree = WIN32API. freelibrary (dlladdr );
}
}
}
This small code contains a lot of technical details. We need to know what the function name is restructured when the unmanaged code exports the call method, so I uploaded the PE File Viewer example;
Marshal is a very powerful P/invoke class. It can be seen as a reflection of Platform calls. The marshal. getdelegateforfunctionpointer method gets unmanagedfunctionpointer type delegation through an unmanaged memory pointer;
Summary: in fact, dynamic calling is to allow us to have more exposure to the underlying knowledge. Everything is understandable, but kung fu is not at home;