#c #windows #winapi #file-locking
#c #Windows #winapi #блокировка файла
Вопрос:
У меня есть класс сопоставления файлов, который позволяет мне также блокировать файл для исключительного использования моим процессом с помощью функции Win32 API LockFileEx() .
bool FileMapping::lockFile(bool wait) {
if (isFileLocked())
return true;
// We want an exclusive lock.
DWORD flags = LOCKFILE_EXCLUSIVE_LOCK;
// If we don't want the thread to block, we have to set the appropriate flag.
if (!wait)
flags |= LOCKFILE_FAIL_IMMEDIATELY;
m_isFileLocked = LockFileEx(m_fileDesc, flags, 0, (DWORD) m_mappingLength, (DWORD) (((uint64_t) m_mappingLength) >> 32), NULL);
return m_isFileLocked;
}
Всякий раз, когда я добираюсь до LockFileEx()
вызова, я получаю нарушение доступа:
Необработанное исключение в 0x7466c2ec в tftpServer.exe : 0xC0000005:
местоположение чтения 0x00000008 с нарушением доступа.
Дескриптор файла m_fileDesc
определенно является допустимым дескриптором (отображение файла в память с помощью этого дескриптора работает) и m_mappingLength
представляет собой просто a size_t
, содержащий длину отображаемой части файла в байтах.
У кого-нибудь есть идеи, как это исправить?
Комментарии:
1. Указатель this равен нулю. Вы вызываете этот метод для нулевого объекта сопоставления файлов.
Ответ №1:
Ваш последний аргумент NULL
, в то время как он должен быть указателем на OVERLAPPED
структуру. Ошибка о местоположении чтения 0x00000008, вероятно, соответствует документированному требованию о том, что:
Вы должны инициализировать элемент hEvent допустимым дескриптором или нулем.
Учитывая hEvent
, что элемент появляется после двух указателей, при 32-разрядной компиляции он будет составлять 8 байт от начала структуры. So LockFileEx
, вероятно, пытается прочитать участника hEvent и выходит из строя.
Комментарии:
1. Упс, я, должно быть, упустил это из виду. Теперь я создал ПЕРЕКРЫВАЮЩУЮСЯ структуру и передаю ее адрес в LockFileEx(), и это работает. Спасибо вам за вашу помощь.
2. Я только что был укушен той же оплошностью. В документах MSDN это должно быть выделено жирным шрифтом! 🙂
Ответ №2:
Цитирование документов, на которые вы ссылаетесь:
lpOverlapped [вход, выход]
Указатель на ПЕРЕКРЫВАЮЩУЮСЯ структуру, которую функция использует с запросом блокировки. Эта структура, которая требуется, содержит смещение файла в начале диапазона блокировки. Вы должны инициализировать элемент hEvent допустимым дескриптором или нулем.
Итак, ваш последний аргумент неверен.
Комментарии:
1. Упс, я, должно быть, упустил это из виду. Теперь я создал ПЕРЕКРЫВАЮЩУЮСЯ структуру и передаю ее адрес в LockFileEx(), и это работает. Спасибо за вашу помощь. Я знаю о проблеме с 5-м аргументом, если
size_t
он равен 32 битам. Вот почему я сначала привел его к uint64_t , поэтому у меня есть 64-битное значение для выполнения сдвига. Я знаю, что на 32-разрядной платформе этот параметр всегда должен быть равен нулю, но я хотел, чтобы он работал как на 32-разрядных, так и на 64-разрядных платформах, поэтому я выбрал приведение и сдвиг.