Calling Win32 DLLs in C# with P/Invoke
http://msdn.microsoft.com/msdnmag/issues/03/07/NET/
Now let's look at the direction in which string information is being passed between your code and the unmanaged function. There are two ways that you can know which direction the information is being passed in when working with strings. The first and most reliable method is to understand the purpose of the parameter in the first place. For example, if you are calling a parameter with a name like CreateMutex and it takes a string, then you can imagine that the string information passes from your application to the API function. Meanwhile, if you call GetUserName, then the function name suggests that string information passes from the function to your application.
In addition to the rationalization approach, the second way to find out which direction the information flows in is to look for the letter "C" in the API parameter type. For example, the GetUserName API function's first parameter is defined as type LPTSTR, which stands for long-pointer to a Unicode or ANSI string buffer. But CreateMutex's name parameter is typed as LTCTSTR. Notice that here you have the same type definition, but with the addition of the letter "C" to indicate that the buffer is constant and will not be written to by the API function.
Once you have established whether the text parameter is input only or input/output, you can determine which CLR type to use for the parameter type. Here are the rules. If the string parameter is input only, use the System.String type. Strings are immutable in managed code, and are well suited to be used as buffers that will not be changed by the native API function.
If the string parameter
can be input and/or output,
then use the System.StringBuilder type.
The StringBuilder type is a useful class library type that helps you build strings efficiently, and it happens to be great for passing buffers to native functions that the functions fill with string data on your behalf. Once the function call has returned, you need only call ToString on the StringBuilder object to get a String object.
The GetShortPathName API function is great for showing when to use String and when to use StringBuilder because it takes only three parameters: an input string, an output string, and a parameter that indicates the length in characters of the output buffer.
The commented documentation for the unmanaged GetShortPathName function in Figure 3 indicates both an input and output string parameter. This leads to the managed extern method definition, also shown in Figure 3. Notice that the first parameter is marshaled as a System.String because it is an input-only parameter. The second parameter represents an output buffer, and System.StringBuilder is used.
------------------------------------------------------------------------------
Advanced .NET Debugging
http://dotnetdebug.blogspot.com/2006/04/pinvoke-and-memory-related-issues.html
--------------------------------------------------------------
Using P/Invoke to Access Win32 APIs
http://www.ondotnet.com/pub/a/dotnet/2002/02/18/cominterop.html
The trickiest part of COM interop
is determining how to map types
between the Win32 call and the static extern method that you declare.
A simple rule of thumb to follow is that
whenever a Win32 method needs a handle or pointer, you should use an IntPtr.
For pointers to strings, you can simply use the .NET String type.
For example, in RegOpenKey, the first parameter is an HKEY type,
which is a handle to an open registry key.
We can map this to a .NET IntPtr type.
The second parameter is a LPCTSTR type,
which is a pointer to a null-terminated string containing the name of the key to open.
This can be mapped to a .NET String type.
--------------------------------------------------------------
Platform Invoke Data Types
http://msdn2.microsoft.com/en-us/library/ac7ay120.aspx
Unmanaged type in Wtypes.h Unmanaged C language type Managed class name Description
HANDLE
void*
System.IntPtr
32 bits on 32-bit Windows operating systems, 64 bits on 64-bit Windows operating systems.
BYTE
unsigned char
System.Byte
8 bits
SHORT
short
System.Int16
16 bits
WORD
unsigned short
System.UInt16
16 bits
INT
int
System.Int32
32 bits
UINT
unsigned int
System.UInt32
32 bits
LONG
long
System.Int32
32 bits
BOOL
long
System.Int32
32 bits
DWORD
unsigned long
System.UInt32
32 bits
ULONG
unsigned long
System.UInt32
32 bits
CHAR
char
System.Char
Decorate with ANSI.
LPSTR (null-terminated string)
char*
System.String or System.Text.StringBuilder
Decorate with ANSI.
LPCSTR
Const char*
System.String or System.Text.StringBuilder
Decorate with ANSI.
LPWSTR
wchar_t*
System.String or System.Text.StringBuilder
Decorate with Unicode.
LPCWSTR
Const wchar_t*
System.String or System.Text.StringBuilder
Decorate with Unicode.
FLOAT
Float
System.Single
32 bits
DOUBLE
Double
System.Double
64 bits