Win32 and how to use two of the other libraries in C #

Simple string

The following is a simple example of a function to accept a string parameter:

The GetDiskFreeSpace BOOL (LPCTSTR lpRootPathName , // root LPDWORD lpSectorsPerCluster , // number of sectors per cluster LPDWORD lpBytesPerSector , // number of bytes per sector LPDWORD lpNumberOfFreeClusters , // number of sectors available LPDWORD lpTotalNumberOfClusters   // fan total area);     

It is defined as the root LPCTSTR. This is a platform-independent string pointer.

Due to the absence of named GetDiskFreeSpace()functions, marshaler will automatically find " A" or " W" variant, and calling the corresponding function. We use a property to tell marshaler, a string type requested API.

The following is the complete definition of the function, so as I defined at the beginning:

[DllImport("kernel32.dll")]static extern bool GetDiskFreeSpace(   [MarshalAs(UnmanagedType.LPTStr)]   string rootPathName,   ref int sectorsPerCluster,   ref int bytesPerSector,   ref int numberOfFreeClusters,   ref int totalNumberOfClusters);

Unfortunately, when I tried to run, this function can not be executed. The problem is that, regardless of the platform on which we have, marshaler in default are trying to find Ansi version of the API, due to the means Windows NT platform uses Unicode strings, so trying to use Unicode strings to call Ansi function will fail. LPTStr

There are two ways to solve this problem: A simple method is to remove the MarshalAsproperty. If you do, will always call the function Aversion, this version has on all platforms if you are concerned, this is a good way. However, this reduces the execution speed of the code, because marshaler To .NET string is converted from multi-byte Unicode, and then calls the function Aversion (the string back to Unicode), the function of the last call Wrelease.

To avoid this situation, you need to tell marshaler, a time to look for it in the Win9x platform Aversion, and look W version on NT platform when. To achieve this purpose, it can be CharSetset as part of the property: DllImport

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]

In my informal timed tests, I found that this practice about five percent faster than the previous method.

For most of the Win32 API, can be set to a string type CharSetproperty and use LPTStr. However, some do not use A/ Wfunction mechanisms, these functions must take a different approach.

String buffer

String type in .NET are immutable type, which means its value will always remain the same. For copy the string value to the buffer function string, the string is not valid. Doing so will destroy at least a temporary buffer created when converting from the string to marshal seal; and in severe damage to the managed heap, which often leads to errors. In either case you can not obtain the correct return value.

To resolve this problem, we need to use other types. StringBuilderType is designed to serve as a buffer, we will use it instead of a string. Here is an example:

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]public static extern int GetShortPathName(   [MarshalAs(UnmanagedType.LPTStr)]   string path,   [MarshalAs(UnmanagedType.LPTStr)]   StringBuilder shortPath,   int shortPathLength);

This function is very simple:

String Builder Builder short path = new String (80); int result = Gets Hort Path Name (@ "d: est.jpg", short path, shortPath.Capacity); string s = shortPath.ToString ();

Please note that StringBuilderthe Capacitytransfer is the buffer size.

Reproduced in: https: //www.cnblogs.com/kevinGao/archive/2011/11/09/2243453.html

Guess you like

Origin blog.csdn.net/weixin_33924770/article/details/93053000