2008-12-05 3 views
11

Je souhaite utiliser la fonction ReadDirectoryChangesW() en mode asynchrone avec la routine d'achèvement d'E/S fournie.Comment utiliser la méthode ReadDirectoryChangesW() avec la routine d'achèvement?

La question est je ne sais pas comment récupérer les informations exactes sur le changement dans la routine d'achèvement (une fonction CALLBACK). routine d'achèvement est défini comme suit:

VOID CALLBACK FileIOCompletionRoutine(
    [in]     DWORD dwErrorCode, 
    [in]     DWORD dwNumberOfBytesTransfered, 
    [in]     LPOVERLAPPED lpOverlapped 
); 

Je me demande l'information est incluse dans la structure LPOVERLAPPED. Mais je ne sais pas comment l'obtenir.

Répondre

3

Excellente question! Il y a 7 ans de retard, mais voici un peu une réponse, ou, plus important, comment le trouver. Ainsi, la documentation ReadDirectoryChangesW:

section

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365465%28v=vs.85%29.aspx

dans les paramètres donne un lien vers FileIOCompletionRoutine:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa364052%28v=vs.85%29.aspx

qui, dans la section Exemples donne un lien vers canal nommé serveur à l'aide d'achèvement Routines :

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365601%28v=vs.85%29.aspx

qui croient ou non, même ne pas utiliser ReadDirectoryChangesW mais donne en fait un exemple en utilisant ReadFileEx, qui aussi utilise FileIOCompletionRoutine:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365468%28v=vs.85%29.aspx

et vous pouvez voir un exemple de les utiliser ces deux fonctions (ReadFileEx et CompletedReadRoutine (ce qui est une implémentation de la fonction de rappel définie par l'application FileIOCompletionRoutine)) dans ce morceau de code:

// CompletedWriteRoutine(DWORD, DWORD, LPOVERLAPPED) 
// This routine is called as a completion routine after writing to 
// the pipe, or when a new client has connected to a pipe instance. 
// It starts another read operation. 

VOID WINAPI CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten, 
    LPOVERLAPPED lpOverLap) 
{ 
    LPPIPEINST lpPipeInst; 
    BOOL fRead = FALSE; 

// lpOverlap points to storage for this instance. 

    lpPipeInst = (LPPIPEINST) lpOverLap; 

// The write operation has finished, so read the next request (if 
// there is no error). 

    if ((dwErr == 0) && (cbWritten == lpPipeInst->cbToWrite)) 
     fRead = ReadFileEx( 
     lpPipeInst->hPipeInst, 
     lpPipeInst->chRequest, 
     BUFSIZE*sizeof(TCHAR), 
     (LPOVERLAPPED) lpPipeInst, 
     (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedReadRoutine); 

// Disconnect if an error occurred. 

    if (! fRead) 
     DisconnectAndClose(lpPipeInst); 
} 

// CompletedReadRoutine(DWORD, DWORD, LPOVERLAPPED) 
// This routine is called as an I/O completion routine after reading 
// a request from the client. It gets data and writes it to the pipe. 

VOID WINAPI CompletedReadRoutine(DWORD dwErr, DWORD cbBytesRead, 
    LPOVERLAPPED lpOverLap) 
{ 
    LPPIPEINST lpPipeInst; 
    BOOL fWrite = FALSE; 

// lpOverlap points to storage for this instance. 

    lpPipeInst = (LPPIPEINST) lpOverLap; 

// The read operation has finished, so write a response (if no 
// error occurred). 

    if ((dwErr == 0) && (cbBytesRead != 0)) 
    { 
     GetAnswerToRequest(lpPipeInst); 

     fWrite = WriteFileEx( 
     lpPipeInst->hPipeInst, 
     lpPipeInst->chReply, 
     lpPipeInst->cbToWrite, 
     (LPOVERLAPPED) lpPipeInst, 
     (LPOVERLAPPED_COMPLETION_ROUTINE) CompletedWriteRoutine); 
    } 

// Disconnect if an error occurred. 

    if (! fWrite) 
     DisconnectAndClose(lpPipeInst); 
} 

ce n'est pas une grande réponse (je n'explorais si J'ai même voulu utiliser ces fonctions, moi-même), mais cela devrait aider les gens à démarrer.

Voir aussi:

https://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx

Questions connexes