2010-03-16 11 views
7

मैं एक 64 बिट प्रक्रिया में MapViewOfFile का उपयोग करने की कोशिश कर रहा हूं जो पहले से ही 32 बिट प्रक्रिया की स्मृति में मैप किया गया है। यह विफल रहता है और मुझे "पहुंच से वंचित" त्रुटि देता है। क्या यह एक ज्ञात विंडोज सीमा है या क्या मैं कुछ गलत कर रहा हूं? समान कोड 2 32 बिट प्रक्रियाओं के साथ ठीक काम करता है।MapViewOfFile 32 बिट और 64 बिट प्रक्रियाओं के बीच साझा किया गया

कोड तरह इस तरह दिखता है:

hMapFile = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, szShmName); 
if (NULL == hMapFile) 
{ /* failed to open - create new (this happens in the 32 bit app) */ 
    SECURITY_ATTRIBUTES sa; 
    sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
    sa.bInheritHandle = FALSE; 
    /* give access to members of administrators group */ 
    BOOL success = ConvertStringSecurityDescriptorToSecurityDescriptor(
      "D:(A;OICI;GA;;;BA)", 
      SDDL_REVISION_1, 
      &(sa.lpSecurityDescriptor), 
      NULL); 
    HANDLE hShmFile = CreateFile(FILE_XXX_SHM, 
      FILE_ALL_ACCESS, 0, 
      &sa, 
      OPEN_ALWAYS, 0, NULL); 

    hMapFile = CreateFileMapping(hShmFile, &sa, PAGE_READWRITE, 
      0, 
      SHM_SIZE, 
      szShmName); 

    CloseHandle(hShmFile); 
} 

// this one fails in 64 bit app 
pShm = MapViewOfFile(hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, SHM_SIZE); 
+0

क्या आपने जांच की है कि पथ वर्चुअलस्टोर निर्देशिका पर रीडायरेक्ट हो रहा है या नहीं? प्रक्रिया मॉनीटर मदद कर सकता है। – bk1e

उत्तर

9

जब आप 32-बिट अनुप्रयोग में CreateFile कहते हैं, आप साझा पैरामीटर, जो कोई साझा करने की अनुमति दी है इसका मतलब के लिए 0 गुजर रहे हैं। FILE_SHARE_READ | FiLE_SHARE_WRITE में बदलना शायद सही दिशा में एक कदम होगा।

संपादित करें: मैं सिर्फ एक साथ एक डेमो है कि काम करता है मार पड़ी है (कम से कम मेरे लिए):

#include <windows.h> 
#include <iostream> 

static const char map_name[] = "FileMapping1"; 
static const char event1_name[] = "EventName1"; 
static const char event2_name[] = "EventName2"; 

int main() { 
    HANDLE mapping = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, map_name); 

    if (NULL == mapping) { 
     std::cout << "Calling CreateFile\n"; 
     HANDLE file = CreateFile("MappedFile", 
      FILE_ALL_ACCESS, 
      FILE_SHARE_READ | FILE_SHARE_WRITE, 
      NULL, 
      OPEN_ALWAYS, 
      0, 
      NULL); 
     std::cout << "Creating File mapping\n"; 
     mapping = CreateFileMapping(file, NULL, PAGE_READWRITE, 0, 65536, map_name); 

     std::cout << "Closing file handle\n"; 
     CloseHandle(file); 
    } 

    std::cout << "Mapping view of file\n"; 
    char *memory = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 65536); 
    if (memory == NULL) { 
     std::cerr << "Mapping Failed.\n"; 
     return 1; 
    } 
    std::cout << "Mapping succeeded\n"; 

    HANDLE event = CreateEvent(NULL, false, false, event1_name); 

    if (GetLastError()==ERROR_ALREADY_EXISTS) { 
     std::cout <<"Waiting to receive string:\n"; 
     WaitForSingleObject(event, INFINITE); 
     std::cout << "Received: " << memory; 
     HANDLE event2 = CreateEvent(NULL, false, false, event2_name); 
     SetEvent(event2); 
    } 
    else { 
     char string[] = "This is the shared string"; 
     std::cout << "Sending string: " << string << "\n"; 
     strncpy(memory, string, sizeof(string)); 
     SetEvent(event); 
     HANDLE event2 = CreateEvent(NULL, false, false, event2_name); 
     WaitForSingleObject(event2, INFINITE); 
    } 
    return 0; 
} 

32- या 64-बिट निष्पादनयोग्य का कोई भी संयोजन ठीक से काम करने लगता है।

संपादित 2: नोट, हालांकि, यह पूरी तरह से डेमो-स्तरीय कोड है। उदाहरण के लिए, प्रत्येक साझा ऑब्जेक्ट का नाम सामान्य रूप से अन्य प्रोग्रामों के साथ आकस्मिक टकराव के खिलाफ सुनिश्चित करने के लिए एक GUID-string होना चाहिए। मैंने बहुत कम त्रुटि जांच भी छोड़ दी है, मामूली विस्तार का उल्लेख न करें कि यह कोड कुछ भी उपयोगी नहीं करता है।

+0

धन्यवाद जैरी, यह दिलचस्प है कि यह आपके लिए काम करता है। मुझे नहीं लगता कि यह मेरी समस्या है हालांकि कोई साझाकरण ध्वज केवल CreateFile को पास नहीं किया गया है; वह फ़ाइल तुरंत बंद है इसलिए इसे लागू नहीं करना चाहिए। इसके अलावा यह 32-बिट ऐप्स के बीच साझा करने के लिए ठीक काम करता है, उनमें से एक 64 बिट होने पर ही टूट जाता है। हालांकि मैं आपका कोड चलाने की कोशिश करूंगा। –

+1

मुझे लगता है कि मैंने इसे समझ लिया। फ़ाइल का आकार एक संरचना के आकार के आधार पर निर्धारित किया गया था जो 64 बिट सिस्टम पर बड़ा है क्योंकि टाइम_टी 64 बिट है और हम 32 बिट बिल्डों पर अभी भी 32 बिट होने के लिए हमारे टाइम_ट को मजबूर कर रहे हैं। किसी कारण से क्षेत्र का आकार निर्दिष्ट करना जो बड़ा है तो MapViewOfFile पर मौजूद एक्सेस अस्वीकृत के साथ विफल रहता है। धन्यवाद! –

संबंधित मुद्दे