2013-02-07 22 views
7

我有一個應用程序有一個共享內存區域定義CreateFileMapping我試圖從另一個應用程序讀取該內存。爲什麼CreateFileMapping返回「文件已存在」?

我嘗試這樣做:

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

,但我得到:

當該文件已存在

可能是什麼問題不能創建一個文件?

+2

圍繞winapi調用你的包裝是否每次調用後都無條件地檢查'GetLastError'?希望'CreateFileMapping'返回一個有效的句柄**和**給後面的'GetLastError'返回'ERROR_ALREADY_EXISTS'(如果它是你所期望的,這實際上不是一個錯誤)。 –

+0

我在CreateFileMapping上調用之後立即調用GetLastError,如果我在創建文件映射之前關閉創建文件映射的應用程序:操作成功完成 – opc0de

+0

@ opc0de不要這樣做。當文檔說要這樣做時,只調用'GetLastError'。這就是當'CreateFileMapping'返回NULL時。 –

回答

15

並非所有將GetLastError()值設置爲非成功都是錯誤。根據函數的返回值首先區分錯誤,並檢查GetLastError()以獲得有關發生的種錯誤的更多信息。

對於已經存在的映射,CreateFileMapping在案,以返回一個有效的句柄GetLastError()值設置爲ERROR_ALREADY_EXISTS。在這種情況下,錯誤值爲信息:如果您有興趣在打開映射之前檢查它是否有效,但這不是錯誤。通過測試返回值爲NULL來檢測失敗。否則,你只需繼續使用手柄。

P.S.如果您想確保該部分在打開之前已存在,則可以使用OpenFileMapping,這將對不存在的部分失敗,而不是創建新的部分。

+0

在這種情況下,共享應用程序會調用'CreateFileMapping()'來共享數據,閱讀應用程序應該使用'OpenFileMapping()'而不是'CreateFileMapping()'讀取共享數據。如果OpenFileMapping()失敗,那麼共享應用程序不會共享任何數據(除非發生另一個錯誤,例如閱讀應用程序無權訪問共享應用程序的映射)。如果它不存在,我不會有一個閱讀應用程序創建映射,除非它打算共享它自己的數據。 –

+0

如果我希望他們能夠以任何順序啓動(而不是等待/重試可能的比賽),我會有一個閱讀應用程序創建映射,這有時很重要。 OP的例子提供了文件映射的大小,所以他顯然知道其他應用程序足以做出決定。 –

相關問題