Иногда при использовании управляемого кода приходится использовать неуправляемые типы. В основном это необходимо при вызове функции из 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.