Newsgroup: it.comp.programmare.win32
Titolo: [API Win32] Problema con NamedPipe

Salve a tutti.
Sto facendo delle prove da principiante di interprocess communication
con le NamedPipe di Win32. Ho creato 2 programmini, un server ed un
client, il server crea una named pipe bloccante e poi ci scrive con
WriteFile sopra una stringa; dall'altra parte il client sta in wait su
una ReadFile in attesa della stringa.
La pipe nel server l'ho creata cosi':
hPipe = CreateNamedPipe( 
          lpszPipename,             
          PIPE_ACCESS_DUPLEX,       
          PIPE_TYPE_BYTE |       
          PIPE_READMODE_BYTE |   
          PIPE_WAIT,                
          PIPE_UNLIMITED_INSTANCES, 
          80,                  
          80,                  
          5000,             
          NULL);
poi, dopo la ConnectNamedPipe ho l'istruzione WriteFile.
Nel client apro la pipe cosi':
hPipe = CreateFile(lpszPipename,
		GENERIC_READ | GENERIC_WRITE,
		0,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL
		);
e poi faccio la ReadFile.
Il client si blocca correttamente sulla ReadFile in attesa di leggere
qualcosa, poi pero' la WriteFile del server non rientra ma mi compare
l'errore (riferito al server):
Application Error
the instruction at "0x77..." referenced memory at "0x00...". The
memory could not be "written"
clicco sull'OK di questa finestra e ottengo un errore uguale (cambia
solo l'indirizzo dell'istruzione che ha provocato l'errore) per il
client: visto che il client era bloccato sulla ReadFile deduco che
anche lei non e' ritornata ma ha provocato questo errore.
Perche' non riesco a scrivere sulla pipe?
Magari la causa dell'errore sara' banale ma non riesco a trovarla.
Ringrazio chiunque possa aiutarmi.
Saluti.

Sei sicuro che i buffer che hai passato alla WriteFile e alla ReadFile 
siano validi?
Hai controllato che la lunghezza che passi alle due operazioni sia 
effettivamente corrispondente alla dimensione allocata?
-- 
Valter Minute
min...@inwind.it
 (the reply address of this message is invalid)

 con le NamedPipe di Win32.
Solo un'annotazione, giusto per sicurezza: ricorda che le named pipes non
sono supportate da Windows 9x, ma solo da Windows NT e 2000.
---
Bye! Lorenzo Lutti
http://antani.virtualave.net/

 effettivamente corrispondente alla dimensione allocata?
si'.
Grazie comunque, saluti.

 sono supportate da Windows 9x, ma solo da Windows NT e 2000.
grazie, sto lavorando con Windows NT 4.
Saluti.

E' strano poichè l'errore che riporti parzialmente sembra indicare che il 
sistema ha provato ad accedere a sezioni di memoria non scrivibili e questo 
mi ha fatto (erroneamente) pensare a un puntatore non valido o ad un buffer 
sottodimensionato.
Utilizzi per caso la lettura/scrittura in modalità overlapped?
Prova a postare un frammento di codice un po' più esteso con la 
read/writefile.


 read/writefile.
//////////
//server:
//////////
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; 
	HANDLE hPipe;
	char stringa[80]="msg dal server";
	hPipe = CreateNamedPipe( 
			lpszPipename,             // pipe name 
			PIPE_ACCESS_DUPLEX,       // read/write access 
			PIPE_TYPE_MESSAGE |       // message type pipe 
			PIPE_READMODE_MESSAGE |   // message-read mode 
			PIPE_WAIT,                // blocking mode 
			1,//PIPE_UNLIMITED_INSTANCES, // max. instances  
			8,                  // output buffer size 
			8,                  // input buffer size 
			5000,             // client time-out 
			(LPSECURITY_ATTRIBUTES) NULL);// no security attribute 
	if(hPipe == INVALID_HANDLE_VALUE) 
	{
		MessageBox(NULL,"Errore CreateNamedPipe","Server",MB_OK); 
		return -1;
	}
 
    if ( ConnectNamedPipe(hPipe, NULL) ) 
	{
		MessageBox(NULL,"server: ho aperto la pipe","Server",MB_OK);
		if( WriteFile(hPipe, stringa, 
                              strlen(stringa)+1, 
                              NULL, NULL) == 0 )
		{
			MessageBox(NULL,"Errore in scrittura","Server",MB_OK);
			return -2;
		}
	} 
    else 
	{
        MessageBox(NULL,"Errore in attesa","Server",MB_OK);
        CloseHandle(hPipe); 
		return -3;
	}
    return 0;
}
/////////
//client:
/////////
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
 	HANDLE hPipe;
	LPTSTR lpszPipename = "\\\\.\\pipe\\mynamedpipe"; 
	char stringa[80];
	hPipe = CreateFile(	
			lpszPipename,
			GENERIC_READ | GENERIC_WRITE,
			FILE_SHARE_READ,
			NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,
			NULL);
	if (hPipe != INVALID_HANDLE_VALUE)
	{
		if(ReadFile(hPipe,stringa,sizeof(stringa),NULL,NULL) != 0 )
		{
			MessageBox(NULL,stringa,"Client",MB_OK);
		}
		else	
		{
			DWORD errore=GetLastError();
			sprintf(stringa,"Errore numero %d",errore);
			MessageBox(NULL,stringa,"Client",MB_OK);
		}
	}
	else
	{
		MessageBox(NULL,"Errore in apertura","Client",MB_OK);
		return -1;
	}
	return 0;
}
Grazie, Saluti.

Il 4° parametro della Write/ReadFile non può essere NULL!
Dall help di WriteFile:
"lpNumberOfBytesWritten 
[out] Pointer to the variable that receives the number of bytes written. 
WriteFile sets this value to zero before doing any work or error checking. 
Il fatto che il valore sia sempre settato a 0 prima della lettura scrittura 
(cosa che avviene sia per la readfile che per la writefile) implica che 
deve trattarsi di un puntatore valido.
L'unico caso particolare è quello dell'I/O overlapped in cui il numero di 
byte letti viene tornato tramite l'apposita struttura (5° parametro di 
Write/ReadFile).


 Write/ReadFile).
E' proprio come dici tu!
Grazie tante, adesso funziona tutto.
Saluti.