Использование вызо­вов P/Invoke в C#

Иногда при исполь­зо­ва­нии управ­ля­е­мо­го кода при­хо­дит­ся исполь­зо­вать неуправ­ля­е­мые типы. В основ­ном это необ­хо­ди­мо при вызо­ве функ­ции из dll. И основ­ная про­бле­ма, кото­рая воз­ни­ка­ет при объ­яв­ле­нии функ­ций это сопо­став­ле­ние неуправ­ля­е­мых типов (типов C++) и управ­ля­е­мых типов C#.

Использовать управ­ля­е­мый код очень про­сто. И он предо­став­ля­ет про­стые спо­со­бы обер­нуть управ­ля­е­мым кодом любую dll.
Например:

BOOL KernelIoControl(
  DWORD dwIoControlCode,
  LPVOID lpInBuf,
  DWORD nInBufSize,
  LPVOID lpOutBuf,
  DWORD nOutBufSize,
  LPDWORD lpBytesReturned
);

мож­но обер­нуть как:
[DllImport(“Coredll.dll”, SetLastError=“true”, EntryPoint = “KernelIoControl”, CharSet = CharSet.Unicode)] public extern static bool KernelIoControl(
uint dwIoControlCode,
IntPtr lpInBuf,
uint nInBufSize,
IntPtr lpOutBuf,
uint nOutBufSize,
ref uint lpBytesReturned);
После чего лег­ко исполь­зо­вать:
Основная слож­ность в выбо­ре типа в C# соот­вет­ству­ю­ще­го неуправ­ля­е­мо­му типу. Привожу сле­ду­ю­щую таб­ли­цу при­ве­де­ния типов. Она не может пре­тен­до­вать на абсо­лют­ную пол­но­ту и точ­ность, но может являть­ся отправ­ной точ­кой.

C/C++ C#
HANDLE, LPDWORD, LPVOID, void* IntPtr
LPCTSTR, LPCTSTR, LPSTR, char*, const char*, Wchar_t*, LPWSTR String [in], StringBuilder [in, out]
DWORD, unsigned long, Ulong UInt32, [MarshalAs(UnmanagedType.U4)]
bool bool
LP<struct> [In] ref <struct>
SIZE_T uint
LPDWORD out uint
LPTSTR [Out] StringBuilder
PULARGE_INTEGER out ulong
WORD uInt16
Byte, unsigned char byte
Short Int16
Long, int Int32
float single
double double
NULL pointer IntPtr.Zero
Uint Uint32

Данная таб­лич­ка взя­та отсю­да, но будет посте­пен­но допол­нять­ся и видо­из­ме­нять­ся.
Смотрите так­же ста­тью в MSDN.

Оставьте комментарий