C # series of articles on interoperability:
C # Introduction to interoperability (I): C # Introduction to interoperability
C # Introduction to interoperability series (II): use the platform to call Win32 Functions
C # Introduction to interoperability series (III): data sending and processing in Platform calls
C # Introduction to interoperability series (4): Calling COM components in C #
Summary of this topic
Introduction to data sending
Win32 Data Type
Processing of sending strings
Handling of sending struct
Processing of mail class
Summary
I. Introduction to data sending
When I saw this topic, the first question was definitely-What is data mail? (In this series of topics, assuming that a friend asks a question to explain the concept, I hope that you can take the question to learn the content of this topic, and you can also use this method during your normal learning process, I personally think this method can improve my learning efficiency. Even though it may be slow in the learning process, this method will have a deeper impression on the knowledge points you have seen. It is far faster than reading it. In the end, I find that there is not much better to remember. Here I will share this learning method, and I think that acceptable friends can try it during normal learning, if you think it is not good, I believe you will certainly have a better way of learning .)The explanation for this problem is,Data encapsulation is a process in which data is transmitted between the hosted memory and the unmanaged memory by using the parameters and returned values of the method during the interoperability of unmanaged functions in the managed code, the process of data sending and processing is completed by the CLR (when the common language is running) Sending and Processing Service (that is, the sending and splitting tool )..
The feater mainly performs three tasks:
Convert data from managed type to unmanaged type or from unmanaged type to managed type
Copy converted data from managed code memory to unmanaged memory or from unmanaged memory to managed memory
After the call is complete, release the memory allocated during the sending process.
Ii. Win32 Data Types
When you perform interoperability between unmanaged code, data is certainly sent and delivered. However, there are two types of data to be processed during sending: the type that can be directly copied to the local structure (blittable) and the type that is not directly copied to the local structure (non-bittable ). The following describes the two data types.
2.1 types that can be directly copied to the local structure
In hosted code and unmanaged code, the data types are different in the representation of hosted memory and unmanaged memory. For this reason, we need to mail the data for processing, so that when an unmanaged function is called in the managed code, the correct incoming parameters are passed to the unmanaged function and the correct return values are returned to the managed code. However, not all data types have different forms in the memory of the two, in this case, we call the data type with the same performance in the managed memory and non-managed memory-the type that can be directly copied to the local structure,These data types can be passed between hosted and unmanaged code without the need for the unblocking and unblocking tool for any special processing., The following lists some simple data types that are copied directly to the local structure:
Windows Data Type |
Unmanaged Data Types |
Managed Data Type |
Managed Data Types |
BYTE/Uchar/UInt8 |
Unsigned char |
System. Byte |
Unsigned 8-digit integer |
Sbyte/Char/Int8 |
Char |
System. SByte |
Signed 8-digit integer |
Short/Int16 |
Short |
System. Int16 |
Signed 16-digit integer |
USHORT/WORD/UInt16/WCHAR |
Unsigned short |
System. UInt16 |
Unsigned 16-digit integer |
Bool/HResult/Int/Long |
Long/int |
System. Int32 |
Signed 32-bit integer |
DWORD/ULONG/UINT |
Unsigned long/unsigned int |
System. UInt32 |
Unsigned 32-bit integer |
INT64/LONGLONG |
_ Int64 |
System. Int64 |
Signed 64-bit integer type |
UINT64/DWORDLONG/ULONGLONG |
_ Uint64 |
System. UInt64 |
Unsigned 64-bit integer |
INT_PTR/hANDLE/wPARAM |
Void */int or _ int64 |
System. IntPtr |
Signed pointer type |
HANDLE |
Void * |
System. UIntPtr |
Unsigned pointer type |
FLOAT |
Float |
System. Single |
Single-precision floating point number |
DOUBLE |
Double |
System. Double |
Double-precision floating point number |
In addition to the simple types listed in the table above, there are also some replication types that can be directly copied to the local structure:
1) Data elements can be directly copied to an array of one yuan in the local structure, such as an integer array or a floating point group.
2) it only contains information that can be directly copied to the local structure.FormatValue Type
3) All member variables are the types that can be copied to the local structure and usedFormatType mails
The format mentioned above refers to the type that is explicitly specified when the memory layout of the member is declared during the type definition. Modify the specified type with the StructLayout attribute in the code, and set the LayoutKind attribute of StructLayout to Sequential or Explicit. For example:
Using System. Runtime. InteropServices;
// The following struct can also be directly copied to the local structure.
[StructLayout (LayoutKind. Sequential)]
Publicstruct Point {
Publicint x;
Publicint y;
}
. 2 types that are not directly copied to the local structure
If a type is not a type that can be directly copied to the local structure, it is a type that is not directly copied to the local structure. Because some types of memory are different in the form of hosted memory and unmanaged memory,For this type, the feater needs to convert the data type before copying the data to the called function., The following lists some data types that are not directly copied to the local structure:
Windows Data Type |
Unmanaged Data Types |
Managed Data Type |
Managed Data Types |
Bool |
Bool |
System. Boolean |
Boolean Type |
WCHAR/TCHAR |
Char/wchar_t |
System. Char |
ANSI/Unicode characters |
Maid/maid/ LPCTSTR/LPSTR/LPWSTR/LPTSTR |
Const char */const wchar_t */char */wchar_t * |
System. String |
ANSI String/Unicode String. If the unmanaged code does not need to update this String, the String type is declared in the hosted code using the String type. |
LPSTR/LPWSTR/LPTSTR |
Char */wchar_t * |
System. StringBuilder |
ANSI string/Unicode string. If the unmanaged code needs to update this string, and then the updated string is returned to the managed code, the StringBuilder type is used to declare the string in the managed code. |
In addition to the types listed in the table above, there are many other types that are not directly copied to the local structure, such as other pointer and handle types. After understanding the differences between the blittable and non-blittable types, you can better process data sending in the interoperability process. Below is a brief introduction to some specific data types.
3. Handling of sending strings
In the previous topic, we have already encountered the issue of sending strings. (In the previous topic, we used to pass strings as the In parameter to the Win32 MessageBox function. For details, refer to the previous topic ). In this section, we will introduce the -- mail as the returned value string. The following is a demo Code. The Code mainly calls the Win32 GetTempPath function to obtain the returned temporary path, in this case, you need to return the returned string to the managed code.
// Example of sending the returned values in the managed function back to the managed Function
Class Program
{
// The Win32 GetTempPath function is defined as follows:
// Dword winapi GetTempPath (
// _ In _ DWORD nBufferLength,
// _ Out _ LPTSTR lpBuffer
//); // Mainly pay attention to how to define the function prototype in the managed code [DllImport ("Kernel32.dll", CharSet = CharSet. Unicode, SetLastError = true)]
Publicstaticexternuint GetTempPath (int bufferLength, StringBuilder buffer );
Staticvoid Main (string [] args)
{
StringBuilder buffer = new StringBuilder (300 );
Uint tempPath = GetTempPath (300, buffer );
String path = buffer. ToString ();
If (tempPath = 0)
{
Int errorcode = Marshal. GetLastWin32Error ();
Win32Exception win32expection = new Win32Exception (errorcode );
Console. WriteLine ("an exception occurred when calling an unmanaged function. The exception Message is:" + win32expection. Message );
}
Console. WriteLine ("the unmanaged function is successfully called. ");
Console. WriteLine ("Temp path:" + buffer );
Console. Read ();
}
}
The running result is:
650) this. width = 650; "src =" http://www.bkjia.com/uploads/allimg/131228/163522B22-0.png "/>
Iv. Handling of sending and receiving struct
When we actually call Win32 API functions, we often need to mail out struct, class, and other replication types, the following uses the Win32 function GetVersionEx as an example to demonstrate how to block the struct as a parameter. To call unmanaged code in managed code, we need to first understand the definition of the unmanaged function. The following is the GetVersionEx unmanaged definition (