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