1 Use of DLLImport
Using System;
Using System. Runtime. InteropServices; // namespace
Class Example
{
// Use DllImport to import Win32 MessageBox Functions
[DllImport ("user32.dll", CharSet = CharSet. Unicode)]
Public static extern int MessageBox (IntPtr hWnd, String text, String caption, uint type );
// The method is declared as static. This is required by the P/Invoke method, because there is no // consistent instance concept in this Windows API. Next, note that this method is marked as extern. This indicates that the compiler implements this method through // a function exported from DLL, so the method body is not required.
Static void Main ()
{
// Call the MessageBox function using platform invoke.
MessageBox (new IntPtr (0), "Hello World! "," Hello Dialog ", 0 );
}
}
It is not difficult to use Unmanaged DLL functions. Next we can learn in detail the meaning of the above Code. First, we will introduce what is managed code and what is non-managed code. Then, we will detail the usage of DLLImport and the significance of each field.
2 managed code)
The core of. NET Framework is the execution environment of its Runtime Library, which is called the Common Language Runtime Library (CLR) or. NET Runtime Library. Generally, the code running under the control of CLR is called managed code ).
Code executed by the running database environment (rather than the operating system. Hosted code applications can obtain the Common Language Runtime library service, such as automatic garbage collection, Runtime Library type check, and security support. These services help provide unified managed code application behavior independent of platform and language.
Managed code supports more than 20 types of Microsoft. NET Framework, including C #, J #, Microsoft Visual Basic. NET, Microsoft JScript.. NET, and C ++. All languages share a unified set of class libraries and can be encoded as intermediate languages (IL ). Runtime-aware ompiler compiles the intermediate language (IL) in the Managed execution environment to make it executable locally, and uses array boundary and index check to handle exceptions, garbage collection and other measures to ensure the security of the type.
Using managed code and its compilation in a managed execution environment can avoid many typical programming errors that cause security black holes and unstable programs. Similarly, many unreliable designs automatically enhance security, such as type security checks, memory management, and invalid object release. Programmers can spend more time focusing on application logic design and reduce the amount of code written. This means shorter development time and stronger programs.
To put it simply, managed code is an intermediate language of microsoft. Its main role is. the net framework clr executes the code to compile the source code. That is to say, the managed code acts as a translation function. The source code is in two stages at runtime:
1. source code compilation is managed code. (There are many types of source code, such as VB, C #, J #)
2. The managed code is compiled into a. net platform-specific file (such as a class library or executable file) of the microsoft system ).
2.1 unmanaged code)
Code that is directly executed by the operating system outside the public Language Runtime Library environment. The unmanaged code must provide its own services such as garbage collection, type check, and security support. Unlike the hosted code, the latter obtains these services from the public Language Runtime Library.
Managed code in. net
2.2 What is hosting? What does hosting mean?
The managed code is based on. net metadata format code, run on. net platform, all the exchanges with the operating system are.. net, such as entrusting these functions. net, so it is called managed code. Non-hosted code is the opposite.
For example, l
Vc.net can also use mfc and atl to write programs. They are based on MFC or ATL instead of. NET, so they are non-hosted code. If they are Based on. net, such as C #, VB.net, they are hosted code.
Unmanaged code cannot be explained by. NET.
To put it simply, if the managed code is used,. net can automatically release the data, and the unmanaged code needs to manually release the data.
What is managed C ++
Hosting is a specialized concept of. NET. It advocates a new programming concept, so we can regard "hosting" as ". NET ". The C ++ application triggered by the concept of hosting consists of three parts: hosting code, hosting data, and hosting.
Managed code
The. Net environment provides many core RUNTIME services, such as exception handling and security policies. To be able to use these services, you must provide some information code (metadata) to the runtime environment, which is the managed code. All C # and VB. NET, JScript. NET is hosted by default, but Visual C ++ is not hosted by default. You must use the command line option (/CLR) in the compiler to generate managed code.
Managed Data
Managed Data is closely related to managed code. Managed Data is the data allocated and released by the garbage collector running in the public language. By default, C #, Visual Basic, and JScript. NET data are hosted data. However, by using special keywords, C # data can be labeled as unmanaged data. Visual C ++ data is not hosted by default, even when the/CLR switch is used.
Hosting
Although Visual C ++ data is not hosted by default, you can use the "_ gc" keyword to mark the class as a hosted class when using C ++ managed extensions. As shown in the name, it indicates that the memory of the class instance is managed by the garbage collector. In addition, a Managed class can also be. NET Framework members, which can bring about the benefit that it can correctly perform operations with classes written in other languages, for example, hosted C ++ classes can be inherited from Visual Basic classes. But there are also some restrictions, such as hosting classes can only inherit from one base class.
2.3 How does managed code call unmanaged code (How does c sharp call c ++ code )?
1. COM interop
Specific operations:
A. Use atl to write com service programs
B. Use Tlbimp to convert the com program written by atl to COM DLL
Run the following command:
Tlbimp the com. dll you wrote
Tlbimp is the type library import program attached to the. NET Framework SDK. Use this command to generate a hosted package for an unmanaged com dll.
C. Hosting a client is very simple
Click new and call the corresponding method.
2. P/Invoke
A. Add a DllImport statement and a method call to the Managed Client.
Describes a P/Invoke website, which is mainly a wiki that allows developers to discover, edit, and add PInvoke signatures, user-Defined types and access to win32 and other unmanaged APIs from managed code (c # And VB.net.
. Net developers around the world can easily share their valuable things to the community,
2.4 comparison of managed code and unmanaged code efficiency
3 DllImportAttribute Field
The DllImportAttribute type plays an important role in P/Invoke calls for hosted code. The main function of DllImportAttribute is to instruct CLR which DLL to export the function you want to call. The DLL name is passed to DllImportAttribute as a constructor parameter.
The following table lists all feature fields related to platform calls. For each field, the following table contains its default value and provides a link to obtain information about how to use these fields to define Unmanaged DLL functions. Field
Description
BestFitMapping
Enable or disable the best match ing.
CallingConvention
Specifies the call Convention for passing method parameters. The default value is WinAPI, which corresponds to _ stdcall on 32-bit Intel-based platforms.
CharSet
Control the Rename and the way in which string parameters are sent to the function. The default value is CharSet. Ansi.
EntryPoint
The DLL entry point to be called.
ExactSpelling
Control whether entry points should be modified to correspond to character sets. Different programming languages have different default values.
PreserveSig
Determines whether the managed method signature should be converted to an unmanaged signature that returns HRESULT and the returned value has an additional [out, retval] parameter.
The default value is true (the signature should not be converted ).
SetLastError
Allow the caller to use the Marshal. GetLastWin32Error API function to determine whether an error has occurred while executing the method. In Visual Basic, the default value is true. in C # And C ++, the default value is false.
ThrowOnUnmappableChar
Control exception, convert Unicode characters that cannot be mapped into an ANSI "? "Character.
In addition to the host DLL, DllImportAttribute also contains optional attributes, four of which are particularly interesting: EntryPoint, CharSet, SetLastError, and CallingConvention. Http://www.360doc.com/content/11/0105/09/3877783_84074258.shtml
3.1 entrypoint
The entry point is used to identify the position of the function in the DLL. In a hosted object, the original name or serial number entry point of the target function identifies the function that spans the interactive operation boundary. In addition, you can map the entry point to a different name, which is actually to rename the function.
The possible causes for renaming the DLL function are listed below:
· Avoid using case-sensitive API function names
· Compliant with the current naming standards
· Provide functions of different data types (by declaring multiple versions of the same DLL function)
· Simplified the use of APIs that contain ANSI and Unicode versions
You can use the DllImportAttribute. EntryPoint field to specify the DLL function by name or serial number. If the name of a function in the method definition is the same as that of the DLL at the entry point, you do not need to use the EntryPoint field to explicitly identify the function. Otherwise, use one of the following attributes to indicate the name or serial number:
[DllImport ("dllname", EntryPoint = "Functionname")]
[DllImport ("dllname", EntryPoint = "#123")]
When specifying the entry point name, you can provide a string to indicate the name of the DLL containing the entry point, or you can identify the entry point by serial number. The serial number is prefixed with the # symbol, for example, #1. If this field is omitted, the common language runtime uses the name of the. NET method marked with DllImportAttribute.
The following example shows how to use the EntryPoint field to replace MessageBoxA with MsgBox.
Using System. Runtime. InteropServices;
Public class Win32 {
[DllImport ("user32.dll", EntryPoint = "MessageBoxA")]
Public static extern int MsgBox (int hWnd, String text, String caption, uint type );
}
3.2 CharSet
The DllImportAttribute. CharSet field controls the character string sending process and determines how the Platform calls the function name in the DLL. This topic describes these two actions.
For functions that use string parameters, Some APIs will export two versions of them: the narrow version (ANSI) and the wide version (Unicode ). For example, Win32 API contains the following entry point name of the MessageBox function:
· MessageBoxA
The ANSI format of single-byte characters is provided. It is characterized by attaching A "A" after the entry point name ". The call to MessageBoxA always sends strings in ANSI format, which is common in Windows 95 and Windows 98 platforms.
· MessageBoxW
The Unicode format of double-byte characters is provided. The feature is to append a "W" after the entry point name ". The call to MessageBoxW always sends strings in Unicode format. It is common in Windows NT, Windows 2000, and Windows XP platforms.
The CharSet field accepts the following values:
CharSet. Ansi (default)
· String mail handling
Platform calls are used to mail strings from the hosted format (Unicode) to the ANSI format.
· Name matching
When the DllImportAttribute. ExactSpelling field is true (which is the default value in Visual Basic 2005), the platform call will only search for the name you specified. For example, if MessageBox is specified, the platform call will search for MessageBox. If it cannot find the exact same spelling, it will fail.
When the ExactSpelling field is false (it is the default value in C ++ and C #), the platform will first search for unprocessed aliases (MessageBox). If the unprocessed aliases cannot be found, the processed name (MessageBoxA) will be searched ). Note that the ANSI name matching behavior is different from the Unicode name matching behavior.
CharSet. Unicode
· String mail handling
Platform calls will copy the string from the hosted format (Unicode) to the Unicode format.
· Name matching
When the ExactSpelling field is true (it is the default value in Visual Basic 2005), the platform call will only search for the name you specified. For example, if MessageBox is specified, the platform call will search for MessageBox. If it cannot find the exact same spelling, it will fail.
When the ExactSpelling field is false (it is the default value in C ++ and C #), the platform call first searches for the processed name (MessageBoxW). If the processed name cannot be found, the unprocessed alias (MessageBox) will be searched ). Note that the Unicode name matching behavior is different from the ANSI name matching behavior.
CharSet. Auto
· The Platform calls are selected between the ANSI and Unicode formats of the target platform at runtime.
The following example shows three managed definitions of the MessageBox function used to specify the character set. In the first definition, the CharSet field is omitted to set to the ANSI character set by default.
[DllImport ("user32.dll")]
Public static extern int MessageBoxA (int hWnd, String text, String caption, uint type );
[DllImport ("user32.dll", CharSet = CharSet. Unicode)]
Public static extern int MessageBoxW (int hWnd, String text, String caption, uint type );
[DllImport ("user32.dll", CharSet = CharSet. Auto)]
Public static extern int MessageBox (int hWnd, String text, String caption, uint type );
The name matching rules for CharSet. Ansi and CharSet. Unicode are very different. For Ansi, if EntryPoint is set to "MyMethod" and it exists, "MyMethod" is returned ". If the DLL does not contain "MyMethod", but "MyMethodA" exists, "MyMethodA" is returned ". The opposite is true for Unicode. If you set EntryPoint to "MyMethod" and it exists, "MyMethodW" is returned ". If "MyMethodW" does not exist in the DLL but "MyMethod" exists, "MyMethod" is returned ". If Auto is used, the matching rule is related to the platform (Unicode on Windows NT and Ansi on Windows 98 ). If ExactSpelling is set to true, "MyMethod" is returned only when "MyMethod" exists in the DLL ".
If the DLL function does not process text in any way, you can ignore the CharSet attribute of DllImportAttribute. However, when Char or String data is part of the equation, set the CharSet attribute to CharSet. Auto. In this way, the CLR can use the appropriate character set according to the Host OS. If the CharSet attribute is not explicitly set, the default value is CharSet. Ansi. This default value has a disadvantage, because for Windows 2000, Windows XP, and Windows NT®Interop call, which negatively affects the performance of text parameter sending.
CharSet should be explicitly selected. ansi or CharSet. the CharSet value of Unicode instead of CharSet. the only condition of Auto is that you explicitly specify an export function, which is specific to one of the two Win32 OS types. The ReadDirectoryChangesW API function is an example of this function. It only exists in Windows NT-based operating systems and only supports Unicode. In this case, you should explicitly use CharSet. unicode.
Sometimes, the relationship between character sets of Windows APIS is not obvious. One way to ensure that the function is correct is to check the C-Language header file of the function in the Platform SDK. (If you are not sure which header file to view, you can view the header files of each API function listed in the Platform SDK documentation .) If you find that this API function is indeed defined as A macro mapped to A function name ending with A or W, the character set is related to the function you are trying to call. An example of A Windows API function is the GetMessage API declared in WinUser. h. You may be surprised to find that it has A and W versions.
3.3 SetLastError
SetLastError error handling is very important, but it is often forgotten during programming. When you call P/Invoke, you may also face other challenges-handling the differences between Windows API error handling and exceptions in managed code. I can give you some suggestions.
If you are using P/Invoke to call a Windows API function, you can use GetLastError to find the extended error information, set the SetLastError attribute to true in the DllImportAttribute of the external method. This applies to most external methods.
This causes the CLR to cache errors set by API functions after each call to an external method. Then, in the packaging method, you can obtain the cached error value by calling the Marshal. GetLastWin32Error method defined in the System. Runtime. InteropServices. Marshal type of the class library. My suggestion is to check the expected error values from the API function and raise a perceptible exception for these values. For all other failures (including unexpected failures. win32Exception defined in the ComponentModel namespace, and Marshal. the value returned by GetLastWin32Error is passed to it.
3.4 CallingConvention
CallingConvention. Cdecl: The caller clears the stack. It enables you to call functions with varargs.
CallingConvention. StdCall: the called party clears the stack. It is the default convention for calling unmanaged functions from managed code.
The default value of the CallingConvention field is Winapi, and the latter is the StdCall Convention by default.
CallingConvention is the most important attribute of DllImportAttribute. With this attribute, you can give CLR instructions on which function call conventions should be used for parameters in the stack. The default value of CallingConvention. Winapi is the best option. It works in most cases. However, if this call does not work, you can check the Declaration header file in the Platform SDK to see if the called API function is an abnormal API that does not conform to the call conventions.
Generally, the call conventions of local functions (such as Windows API functions or C-runtime DLL Functions) describe how to push parameters into the thread stack or clear them from the thread stack. Most Windows API functions first push the last parameter of the function into the stack, and then the called function is responsible for clearing the stack. On the contrary, many C-runtime DLL functions are defined to push them into the stack in the order in which method parameters appear in the method signature, and stack cleanup is handed over to the caller.
Fortunately, to call P/Invoke, you only need to let the peripheral devices understand the call conventions. Generally, the default value CallingConvention. Winapi is the best choice. Then, in C Runtime DLL functions and a few functions, you may need to change the Convention to CallingConvention. Cdecl.
3.5 ExactSpelling
ExactSpelling indicates whether the name of the entry point in the unmanaged DLL should be modified to correspond to the CharSet value specified in the CharSet field. If this parameter is set to true, the parameter is set to DllImportAttribute. when the CharSet field is set to the Ansi value of CharSet, append the letter A to the method name, when DllImportAttribute. when the CharSet field is set to the Unicode value of CharSet, W is appended to the method name. The default value of this field is false. Www.2cto.com
3.6 PreserveSig
PreserveSig indicates that the signature of the managed method should not be converted to an unmanaged signature that returns HRESULT and may have an additional [out, retval] parameter corresponding to the returned value.
4 parameter type
You can use the corresponding numeric type directly. (DWORD-> int, WORD-> Int16)
String pointer type in API-> string in. net
Handle (dWord) in API-> IntPtr in. net
In the API, choose structure>. net. Note that in this case, the StructLayout feature should be used to limit the declared structure or Class
5. Some commonly used DLL in DLL6 wince in Win32 APIs