8

WinAPIのMapViewOfFile機能でこの状況に遭遇しました。インターネットで検索しても明らかな修正が見つからなかったので、ここで私の問題と解決策を共有します。

次のスニペットを検討してください。

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  size,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

ある特定のケースでCreateFileMappingは、ハンドルが正常に返されました。GetLastError帰っERROR_ALREADY_EXISTSていたのでcreated == falseMapViewOfFileここで、に渡したのと同じサイズを使用して を呼び出すとCreateFileMapping、 が返され、 :が返さNULLれます。プロセスは管理者権限で実行されていました。GetLastError0x05ERROR_ACCESS_DENIED

MSDN のドキュメントには、この状況が発生する理由についてはまったく言及されていません。では、なぜCreateFileMapping成功するのにMapViewOfFile失敗するのでしょうか。

4

2 に答える 2

9

多くの苦しみの後、最終的にアプリケーションでこのエラーの原因を突き止めました.読み取る要素のサイズではなく、ファイルのサイズ。サイズがわからない場合は 0 にする必要があります。サイズとして渡す値は必要なブロックの長さであるため、これは MapViewOfFile には適用されません。読み書きする。

コードの動作は次のようになります。

const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();

HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
                                  NULL,
                                  PAGE_READWRITE,
                                  0,
                                  0,
                                  name);

if (!handle || handle == INVALID_HANDLE_VALUE)
    exit(GetLastError());

bool created = GetLastError() == 0;

void *block = MapViewOfFile( handle,
                             FILE_MAP_ALL_ACCESS,
                             0,
                             0,
                             size);

if (block == NULL)
    exit(GetLastError());

私が見つけたものを文書化するためにこれをここに置くだけですが、残念ながら、何が原因かわからない場合、このエラーを検索するのは困難です。これにより、他の誰かが数時間を節約できることを願っています。

于 2015-01-03T09:22:48.113 に答える
7

ERROR_ACCESS_DENIEDへの呼び出しから発生する理由はたくさんあると思いMapViewOfFileます。私の特定の状況では、それはsize議論によるものでした。

という事実にヒントがありcreated == falseます。オブジェクト"Global\\Object_Name"がすでに作成されていることを示しています。なんらかの理由で、呼び出しを作成すると、セクションが小さいサイズで初期化されました。見落としのように思えますが、 の 2 番目の呼び出しCreateFileMappingは、より大きなマッピングを要求した場合でも、既存のオブジェクトへのハンドルを喜んで提供します。

MapViewOfFile実際のセクションよりも大きなビューを要求しているため、 nowの呼び出しは失敗します。

したがって、2 番目の呼び出しがMapViewOfFile失敗する同様の状況にある場合は、マップしようとしているサイズを確認してください。

2 番目のプロジェクトが異なる構造アライメントでコンパイルされているため、sizeof()オペレーターが異なる値を決定するか、または他のサイズ決定関数が期待どおりに動作していない可能性があります。

于 2013-04-16T01:24:07.963 に答える