Read the introduction of P/invoke technology, so want to write something, something contains two parts: The knowledge of the record and my understanding and doubt.
procedures for calling unmanaged API functions in managed code R
1, Locate the DLL containing the API;
2. Load DLL
3. Find the API you want in the DLL, then press the parameters into the stack and arrange the data (what does the data mean?). Data marshaling )
4. Transfer execution permissions from managed code to unmanaged code ()
The functions in the DLL are described in order to invoke the
DllImport features to illustrate functions, there are some special functions, such as replacing the original name of the API, see DllImport features.
data type correspondence in unmanaged functions and managed methods: data Marshaling
Converting the data in C # to the data type in the API is data marshaling. There is one default unmanaged type for each. NET Framework type, and the common language runtime uses this unmanaged type to marshal data in managed-to-unmanaged function calls. The string type default unmanaged type is LPTSTR, and you can override the default marshaling by using the MarshalAs property in the C # declaration of an unmanaged function. For example:
[DllImport ("Msvcrt.dll")] public static extern int puts ( [MarshalAs (UNMANAGEDTYPE.LPSTR)] string m);
puts
The default marshaling of parameters for a function has been overridden from the default value of LPTSTR to LPSTR
What is the use of modifying default marshaling? by default, native and managed structures have different layouts in memory, so to successfully pass structures across managed/unmanaged boundaries requires some extra steps to preserve the integrity of the data. ,
What if a struct is used in an API and there is no corresponding managed type in C #? You need to specify custom marshaling for user-defined structures.
You can specify custom marshaling properties for the fields that are passed to an unmanaged function or returned from an unmanaged function and from a class. You can do this by adding the MarshalAs property to a field in a struct or class . You must also use the structlayout property to set the layout of the structure, control the default marshaling for string members, and set the default package size.
In C + +:
1 struct SS 2 {34int A; 5 6 byte b; 7 8 }
Corresponding in C #:
1 class SS 2 3 public int A; 4 public byte b; 5 }
marshaling, which seems to be a data transfer, but why to marshal it? Marshaling is intended to pass data normally in managed memory and unmanaged memory.? Sometimes, for performance reasons, members of a managed structure are rearranged, so it is necessary to use the StructLayoutAttribute attribute to indicate that the structure is a sequential layout. It is also a good idea to explicitly set the structure encapsulation settings to the same settings that are used by the native structure.
Data marshaling--the basic data type correspondence relationship:
Two cases of pointer handling in data marshaling:
First, the ordinary hands
Marshaling is implemented using ref out in C #.
Ii. Types of handle
Using IntPtr in C # for marshaling
marshaling, my understanding is two aspects, encapsulation and delivery. Transmission is like the passing of parameters in a method, and encapsulation is a bit of a point, and sometimes some processing is required before encapsulation. Like the class SS above and the struct SS in C + +, in fact the data A and B in the two are not the same in memory. Details are as follows:
1 1 class SS 2 2 {33 Public int A; 4 4 Public byte b; 5 5 }
It seems that a is in front of B, in fact, in memory is not so, C # class field members of the order in memory is automatically scheduled, that is, not like in the source code, as to why is automatic (auto) Scheduling order, do not know, I hope someone knows the words, and in C + + The order of the class members is the same as the one seen, which is why we have to do some processing before encapsulation, because the members are in the same order in memory!
There is an attribute in C # that can be adjusted in this order, i.e. [StructLayout (layoutkind.sequential)], which is [StructLayout (Layoutkind.auto)] By default when a class is not explicitly decorated. The process is as follows:
class SS { publicint A; Public byte b; }
Registering callback Methods
The handling of the callback function is encountered.