Почему CreateFileMapping возвращает «файл уже существует»?

У меня есть приложение, которое имеет зону общей памяти, определенную с помощью CreateFileMapping , и я пытаюсь прочитать эту память из другого приложения.

Я попробовал это:

handle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE,
             0,$3200, pchar('FileMappingZone'));

Но я понимаю:

Невозможно создать файл, если этот файл уже существует

В чем может быть проблема?

7
nl ja de
Я вызываю GetLastError сразу после вызова CreateFileMapping, если я закрываю приложение, которое создало сопоставление файлов, прежде чем оно говорит: операция завершена успешно
добавлено автор opc0de, источник
@ opc0de Не делай этого. Вызывайте GetLastError только в том случае, если в документации написано об этом. И именно тогда CreateFileMapping возвращает NULL .
добавлено автор David Heffernan, источник
Ваш обозреватель вокруг winapi вызывает проверку GetLastError безоговорочно после каждого вызова? Ожидается, что для CreateFileMapping вернет допустимый дескриптор и для следующего GetLastError , чтобы вернуть ERROR_ALREADY_EXISTS (который на самом деле не является ошибка, если это то, что вы ожидаете).
добавлено автор Anton Kovalenko, источник
@DavidHeffernan GetLastError должен быть рассмотрен в случаях, отличных от ошибок, иногда, в отличие от errno . Но тогда важно not интерпретировать его значение как ошибку.
добавлено автор Anton Kovalenko, источник

1 ответы

Не все, что устанавливает значение GetLastError() для неуспеха, является ошибкой. Важно сначала отличить errors от возвращаемого значения функции и изучить GetLastError() , чтобы получить дополнительную информацию о виде ошибки .

Для сопоставлений, которые уже существуют, CreateFileMapping документируется для возврата допустимого дескриптора и для установки значения GetLastError() в ERROR_ALREADY_EXISTS . В этом случае значение ошибки информационное : оно действительно для его проверки, если вас интересует, существует ли сопоставление, прежде чем вы его открыли, но это не ошибка. Вы обнаруживаете failure , проверяя возвращаемое значение для NULL. В противном случае вы просто продолжаете использовать ручку.

Постскриптум Если вы хотите убедиться, что раздел существует до открытия, вы можете использовать OpenFileMapping , который не удастся для несуществующих разделов вместо создания нового.

15
добавлено
В этом случае приложение для совместного доступа вызовет CreateFileMapping() для обмена данными, а приложение для чтения должно использовать OpenFileMapping() вместо CreateFileMapping() для чтения общих данных. Если OpenFileMapping() терпит неудачу, то приложение общего доступа не делит никаких данных (если не возникает другая ошибка, например приложение чтения, не имеющее прав доступа к сопоставлению приложения совместного использования). У меня не было бы приложения для чтения, создающего сопоставление, если оно еще не существует, если оно не намерено обмениваться данными.
добавлено автор Remy Lebeau, источник
У меня было бы приложение для чтения, создающее сопоставление, если я хочу, чтобы они могли запускаться в любом порядке (и не ждать/повторять с возможными расами), что иногда важно. Пример OP обеспечивает размер для сопоставления файлов, поэтому он, очевидно, знает, что другое приложение достаточно близко, чтобы принять решение.
добавлено автор Anton Kovalenko, источник
Delphi & Lazarus
Delphi & Lazarus
274 участник(ов)

Чат про Delphi и Lazarus