PDA

View Full Version : Chiarimenti GlobalAlloc e altre funzioni per la gestione della memoria


fdfdfdddd
09-11-2006, 10:19
Salve a tutti,

avrei bisogno di alcuni chiarimenti in merito alle funzioni della gestione della memoria su Windows. In particolare il mio scopo è quello di scrivere dei dati di una variabile in un dato processo in una zona di memoria globale e leggere quest'aria in un'altro processo prendendone il contenuto.

Consultando la MSDN, vedo queste funzioni che dovrebbero darmi una mano ...

The GlobalAlloc function allocates the specified number of bytes from the heap. Windows memory management does not provide a separate local heap and global heap.

[I]
The GlobalLock function locks a global memory object and returns a pointer to the first byte of the object's memory block.

al che ho scritto due programmetti di test: questo per "scrivere" l'handle sul disco ...


HGLOBAL myGlobalMemoryHandle;
int myInteger = 270578;
int newInteger = 0;
FILE *fp;

myGlobalMemoryHandle = GlobalAlloc(GMEM_MOVEABLE, sizeof(int));
newInteger = (int)GlobalLock(myGlobalMemoryHandle);
memcpy(&newInteger, &myInteger, sizeof(int));
GlobalUnlock(myGlobalMemoryHandle);

fp = fopen("C:\\test.bin", "wb");
fwrite(&myGlobalMemoryHandle, sizeof(HGLOBAL), 1, fp);
fclose(fp);


e questo per "leggere":


HGLOBAL myMemoryHandle;
FILE *fp;
int myInteger = 0;

if ((fp = fopen("C:\\test.bin", "rb")) != NULL) {
fread(&myMemoryHandle, sizeof(HGLOBAL), 1, fp);
}

myInteger = (int) GlobalLock(myMemoryHandle);


Ma il mio "myInteger" in questo caso rimane a 0.

Sbaglio qualcosa nei programmi oppure uso delle API errate? E se uso api errate ce ne sono che soddisfano la mia esigenza?

andbin
09-11-2006, 10:55
Nota che GlobalLock ritorna un puntatore.

Quindi puoi fare:
HGLOBAL hMem;
int *ptr;

hMem = GlobalAlloc (GMEM_MOVEABLE, sizeof (int));

if (hMem != NULL)
{
ptr = (int*) GlobalLock (hMem);

if (ptr != NULL)
{
*ptr = 12345;

GlobalUnlock (hMem);
}

GlobalFree (hMem);
}

Oppure:
int *ptr;

ptr = (int*) GlobalAlloc (GMEM_FIXED, sizeof (int));

if (ptr != NULL)
{
*ptr = 12345;

GlobalFree ((HGLOBAL) ptr);
}

fdfdfdddd
09-11-2006, 11:17
Innanzi tutto grazie per la risposta.
Mi fai capire quindi che per la scrittura di una zona di memoria globale che andrà letta poi da un'altro processo (un exe per intenderci) la strada è questa.

Il codice d'esempio che hai postato è per la scrittura della detta area di memoria, quindi per la lettura il mio


HGLOBAL myMemoryHandle;
FILE *fp;
int *myInteger = 0;
if ((fp = fopen("C:\\test.bin", "rb")) != NULL) {
fread(&myMemoryHandle, sizeof(HGLOBAL), 1, fp);
}

myInteger = (int*) GlobalLock(myMemoryHandle);


Grazie 1000 ancora!

PS: Sono "costretto" a passare l'handle da un processo all'altro via file ... non mi creerà casino per questo?
Dovrebbe andare bene, giusto?

andbin
09-11-2006, 11:23
Innanzi tutto grazie per la risposta.
Mi fai capire quindi che per la scrittura di una zona di memoria globale che andrà letta poi da un'altro processo (un exe per intenderci) la strada è questa.No alt, attenzione: la memoria allocata con GlobalAlloc è visibile solo all'interno del processo che ha eseguito la allocazione!!!

Con il termine "global" non intende che il blocco è visibile da tutti i processi!!!

P.S.: ho corretto il mio primo esempio sopra, ho scritto in fretta e non ho testato hMem.

fdfdfdddd
09-11-2006, 11:26
Questo "leggerissimo" dubbio l'avevo dal primo momento.

Guarda, perdona se la richiesta banale ... ma sto leggendo e rileggendo la MSDN ma a questo punto non so che pesci prendere.

Non c'è qualche API che mi permette di scrivere un'area condivisa di memoria tramite un processo e leggerla tramite un'altro?

andbin
09-11-2006, 11:35
Non c'è qualche API che mi permette di scrivere un'area condivisa di memoria tramite un processo e leggerla tramite un'altro?Allora prova a leggere: File Mapping (http://search.msdn.microsoft.com/search/Redirect.aspx?title=File+Mapping+%5bBase%5d&url=http://msdn.microsoft.com/library/en-us/memory/base/file_mapping.asp)