LPOVERLAPPED_COMPLETION_ROUTINE is incompatible wi

2019-03-06 06:20发布

问题:

I want to asynchronously write data to file using WriteFileEx from winapi, but I have a problem with callback.

I'm getting follow error: an argument of type "void (*) (DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)" is incompatible with parameter of type "LPOVERLAPPED_COMPLETION_ROUTINE"

What am I doing wrong?

Here is code:

// Callback
void onWriteComplete(
        DWORD dwErrorCode,
        DWORD dwNumberOfBytesTransfered,
        LPOVERLAPPED lpOverlapped) {
    return;
}

BOOL writeToOutputFile(String ^outFileName, List<String ^> ^fileNames) {
    HANDLE hFile;
    char DataBuffer[] = "This is some test data to write to the file.";
    DWORD dwBytesToWrite = (DWORD) strlen(DataBuffer);
    DWORD dwBytesWritten = 0;
    BOOL bErrorFlag = FALSE;

    pin_ptr<const wchar_t> wFileName = PtrToStringChars(outFileName);

    hFile = CreateFile(
        wFileName,              // name of the write
        GENERIC_WRITE,          // open for writing
        0,                      // do not share
        NULL,                   // default security
        CREATE_NEW,             // create new file only
        FILE_FLAG_OVERLAPPED, 
        NULL);                  // no attr. template

    if (hFile == INVALID_HANDLE_VALUE) {
        return FALSE;
    }

    OVERLAPPED oOverlap;
    bErrorFlag = WriteFileEx(
        hFile,           // open file handle
        DataBuffer,      // start of data to write
        dwBytesToWrite,  // number of bytes to write
        &oOverlap,      // overlapped structure
        onWriteComplete),

    CloseHandle(hFile);
}

回答1:

You should start by reading the documentation carefully. This part is of particular import:

The OVERLAPPED data structure must remain valid for the duration of the write operation. It should not be a variable that can go out of scope while the write operation is pending completion.

You are not meeting that requirement, and you need to tackle that issue urgently.

As for the compiler error, that's simple enough. Your callback does not meet the requirements. Again consult the documentation where its signature is given as:

VOID CALLBACK FileIOCompletionRoutine(
  _In_     DWORD dwErrorCode,
  _In_     DWORD dwNumberOfBytesTransfered,
  _Inout_  LPOVERLAPPED lpOverlapped
);

You have omitted CALLBACK which specifies the calling convention.