Ответ 1
Для целей P/Invoke, как вы указали, вы должны использовать IntPtr.Zero
вместо NULL
. Обратите внимание, что это не эквивалентно ключевому слову С# NULL
.
Я пытаюсь настроить ReadFile
для запуска асинхронно и согласно MSDN, мне нужно установить lpNumberOfBytesRead
в null
:
"Используйте NULL для этого параметра, если это асинхронная операция, чтобы избежать потенциально ошибочных результатов."
Например, если у меня есть следующее:
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern bool ReadFile(
IntPtr hFile,
out byte[] aBuffer,
int cbToRead,
IntPtr cbThatWereRead,
ref OVERLAPPED pOverlapped
);
и я называю это так (с намерением иметь 4-й параметр, равный нулю):
Win32API.ReadFile(readHandle, out data_read, Win32API.BUFFER_SIZE, IntPtr.Zero, ref over_lapped);
будет ли это то же самое, что вызвать его с нулевым значением? Если нет, что я должен изменить в объявлении или в самом вызове функции?
Мне также было любопытно, следует ли использовать SafeHandle
или HandleRef
вместо IntPtr
для ссылки hFile
? Я знаю, чтобы убедиться, что я закрываю дескриптор с помощью CloseHandle(IntPtr)
, когда я закончил с этим, просто не уверен, есть ли причина использовать другие две опции над IntPtr
. Я также стараюсь избегать использования небезопасного кода.
EDIT: Как оказалось, я не должен был устанавливать четвертый параметр в IntPtr.Zero
в любом случае, потому что, хотя я работаю асинхронно, он все равно может вернуться сразу. См. Асинхронный дисковый ввод-вывод. Ах, я люблю противоречивые истории.
Для целей P/Invoke, как вы указали, вы должны использовать IntPtr.Zero
вместо NULL
. Обратите внимание, что это не эквивалентно ключевому слову С# NULL
.
Вы не можете назначить значение null для значения. Тип ссылки может быть нулевым, как и в, не ссылаться на экземпляр объекта, но тип значения всегда имеет значение.
IntPtr.Zero - это просто постоянное значение, которое представляет нулевой указатель.
Помните, что в С# >= 2.0 есть ошибка (функция?), где
if (IntPtr.Zero == null)
{
// Won't enter here
}
будет компилироваться правильно, но он никогда не войдет в if
.