سؤال

وأنا أحاول أن استخدام MapViewOfFile في عملية 64 بت على الملف الذي تم تعيينه بالفعل إلى ذكرى عملية 32 بت آخر. فشلت ويعطيني "تم رفض الوصول" خطأ. وهذا يعرف الحد Windows أو أفعل شيئا خاطئا؟ نفس رمز يعمل بشكل جيد مع 2 32BIT والعمليات.

وهذا النوع مدونة يشبه هذا:

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); 
هل كانت مفيدة؟

المحلول

عند استدعاء CreateFile في تطبيق 32 بت، وأنت تمر 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-بت يبدو أن تعمل بشكل جيد.

وEdit2: نلاحظ، مع ذلك، أن هذا هو محض رمز مستوى العرض. فقط على سبيل المثال، يجب أن تحتوي على اسم كل كائن المشتركة عادة سلسلة GUID لضمان عدم الاصطدام العرضي مع البرامج الأخرى. لقد تخطى أيضا قدرا كبيرا من التحقق من الخطأ، ناهيك عن التفاصيل قاصر أن هذا الرمز لا تنجز أي شيء مفيد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top