Question

Sur l'entrée Wikipedia de l'anneau tampon , il y a exemple de code montrant un hack pour UNIX systèmes dans lesquels la mémoire virtuelle adjacente à une partie de la mémoire est mappée . dans la même mémoire physique, implémentant ainsi une mémoire tampon en anneau sans avoir besoin de memcpy , etc. Je me demandais s’il existait un moyen de créer quelque chose de similaire dans Windows ?

Merci, Fraser

Était-ce utile?

La solution

Je n'ai pas vraiment suivi tous les détails de l'exemple dans Wikipedia. Dans cet esprit, vous mappez la mémoire dans Windows à l'aide de CreateFileMapping et MapViewOfFile , cependant MapViewOfFile ne permet pas vous pour spécifier une adresse de base pour le mappage. MapViewOfFileEx peut être utilisé pour spécifier une adresse de base afin peut-être pourriez-vous utiliser une technique similaire.

Je n'ai aucun moyen de savoir si cela fonctionnerait réellement:

// determine valid buffer size
SYSTEM_INFO info;
GetSystemInfo(&info);

// note that the base address must be a multiple of the allocation granularity
DWORD bufferSize=info.dwAllocationGranularity;

HANDLE hMapFile = CreateFileMapping(
             INVALID_HANDLE_VALUE,
             NULL,
             PAGE_READWRITE,
             0,
             bufferSize*2,
             L"Mapping");

BYTE *pBuf = (BYTE*)MapViewOfFile(hMapFile,
                    FILE_MAP_ALL_ACCESS,
                    0,                   
                    0,                   
                    bufferSize);
MapViewOfFileEx(hMapFile,
                    FILE_MAP_ALL_ACCESS,
                    0,                   
                    0,                   
                    bufferSize,
                    pBuf+bufferSize);

Autres conseils

Oh, c'est le sujet qui m'a beaucoup inquiété ces derniers temps. J'avais besoin d'un tampon circulaire optimisé pour Posix sous Windows, principalement à cause de son interface à accès aléatoire, mais je n'avais aucune idée de la façon de le mettre en œuvre. Maintenant, le code proposé par @ 1800 INFORMATION fonctionne parfois, parfois non, mais l'idée est géniale quand même.

Le problème est que MapViewOfFileEx échoue parfois avec ERROR_INVALID_ADDRESS, ce qui signifie qu'il ne peut pas mapper la vue sur pBuf + bufferSize . En effet, MapViewOfFile appelé auparavant sélectionne un espace d'adressage libre de longueur bufferSize (à partir de pBuf ), mais ne garantit pas cette adresse. l'espace à bufferSize * 2 long. Et pourquoi aurions-nous besoin de la mémoire virtuelle bufferSize * 2 ? Parce que notre anneau tampon doit être bouclé. C'est à cela que sert la deuxième vue de mappage. Lorsque le pointeur de lecture ou d'écriture quitte la première vue, il entre dans la deuxième (car ils sont contigus en mémoire), mais en réalité, il recommence au même mappage.

UINT_PTR addr;
HANDLE hMapFile;
LPVOID address, address2;

hMapFile = CreateFileMapping (    // create a mapping backed by a pagefile
    INVALID_HANDLE_VALUE,
    NULL,
    PAGE_EXECUTE_READWRITE,
    0,
    bufferSize*2,
    "Local\\mapping" );
if(hMapFile == NULL) 
    FAIL(CreateFileMapping);

address = MapViewOfFile (    // find a free bufferSize*2 address space
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize*2 );
if(address==NULL) 
    FAIL(MapViewOfFile);
UnmapViewOfFile(address);
// found it. hopefully it'll remain free while we map to it

addr = ((UINT_PTR)address);
address = MapViewOfFileEx (
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize, 
    (LPVOID)addr );

addr = ((UINT_PTR)address) + bufferSize;        
address2 = MapViewOfFileEx (
    hMapFile,
    FILE_MAP_ALL_ACCESS,
    0,                   
    0,                   
    bufferSize,
    (LPVOID)addr);  

if(address2==NULL)      
    FAIL(MapViewOfFileEx);

// when you're done with your ring buffer, call UnmapViewOfFile for 
// address and address2 and CloseHandle(hMapFile)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top