c# - P/Invoke, DllImport, Marshal Structures and Type conversions

P/Invoke as in the following quote provides basically the way to calls into the unmanaged DLLs. the quote is as follow. 

MSDN 写道
P/Invoke is short for Platform Invoke and provides the functionality to access functions, structs, and callbacks in unmanaged DLLs. P/Invoke provides a translation layer to assist developers by allowing them to extend the library of available functionality beyond the managed library of the BCL. To easiest way to understand how to use P/Invoke is to look at some sample applications that use P/Invoke to accomplish a task not possible with managed code.

 

DllImport

 

DllImport has many a attribute, but fortunately you can visit all those attribute from the following page: Using P/Invoke to call Unmanaged APIs from your Managed Classes, attribute include 

  • Name
  • EntryPoint
  • SetLastError
  • CharSet
  • ExactSpelling
  • BestFitMapping
  • Calling Convention
  • Perserve Signature
  • ThrowOnUnmappedChar

Marshalling

 

As for marshalling, 

as it is quoted:

MSDN 写道
Marshalling is the act of converting data such that it can be passed and correctly analyzed between managed and unmanaged program spaces. This marshaling is performed at runtime using the CLR's marshalling service. When using P/Invoke you typically need to marshal classes and structs and control marshalling details using a number of attributes from the System.Runtime.InteropServices namespace.

 

As this is maybe very important for the common types to marshal across platform..

 

Windows Data Type .NET Data Type
BOOL, BOOLEAN Boolean or Int32
BSTR String
BYTE Byte
CHAR Char
DOUBLE Double
DWORD/LPDWORD Int32 or UInt32
FLOAT Single
HANDLE (and all other handle types, such as HFONT and HMENU) IntPtr, UintPtr, or HandleRef
HRESULT Int32 or UInt32
INT Int32
LANGID Int16 or UInt16
LCID Int32 or UInt32
LONG Int32
LPARAM IntPtr, UintPtr, or Object
LPCSTR String
LPCTSTR String
LPCWSTR String
LPSTR String or StringBuilder*
LPTSTR String or StringBuilder
LPWSTR String or StringBuilder
LPVOID IntPtr, UintPtr, or Object
LRESULT IntPtr
SAFEARRAY .NET array type
SHORT Int16
TCHAR Char
UCHAR SByte
UINT Int32 or UInt32
ULONG Int32 or UInt32
VARIANT Object
VARIANT_BOOL Boolean
WCHAR Char
WORD Int16 or UInt16
WPARAM IntPtr, UintPtr, or Object

 

 

StructLayout Attribute

Because we have to marshal types between native and managed code, we have to take care to handle the StructLayout which controls how they end up in the memory (imagine a native function which pass a struct out with special layout from what is expected from managed side or the reverse/inverse.)

 

So what is structLayout is about?

MSDN 写道
In addition to the simple types listed in the type conversion table, many unmanaged functions use structs to pass information more efficiently. The StructLayout attribute allows you to specify how to lay out the data members in managed portions of memory so that they can successfully be referenced in unmanaged portions of memory.

 The following will control the how a StructLayout is 

  • Layout - one of the following kinds
    •    LayoutKind.Sequential
    •    LayoutKind.Union
    •    LayoutKind.Explicit
  • Pack
  • Charset
  • Size

Besisde the explicit PInvoke, there is some implicit invoke - a more accurate way of saying is "C++ Interop (Implicit PInvoke) - whch is said to have better support in 
managed and unmanaged code to exist in the same application/even same file - from unmanaged to managed ones
Better type safety, less tedious to implement, more forgiving if the unmanaged API is modified, makes performance enhancement possible which is not possible with explicit PInvoke.


 

 

References:

Using P/Invoke to call Unmanaged APIs from your Managed Classes

How to : Marshal Structures Using PInvoke

你可能感兴趣的:(C#)