LPOVERLAPPED_COMPLETION_ROUTINE несовместим с функцией

Я хочу асинхронно записать данные в файл с помощью WriteFileEx из winapi, но у меня проблема с обратным вызовом.

Я получаю следующую ошибку: аргумент типа "void (*) (DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverlapped)" несовместим с параметром типа "LPOVERLAPPED_COMPLETION_ROUTINE"

Что я делаю не так?

Вот код:

// 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);
}

person Mike_Device    schedule 06.01.2015    source источник


Ответы (1)


Вам следует начать с внимательного прочтения документации. Эта часть имеет особое значение:

Структура данных OVERLAPPED должна оставаться действительной на протяжении всей операции записи. Это не должна быть переменная, которая может выйти за пределы области видимости, пока операция записи ожидает завершения.

Вы не соответствуете этому требованию, и вам нужно срочно решить эту проблему.

Что касается ошибки компилятора, это достаточно просто. Ваш обратный звонок не соответствует требованиям. Снова обратитесь к документации, где его подпись указана как:

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

Вы пропустили CALLBACK, который определяет соглашение о вызовах.

person David Heffernan    schedule 06.01.2015
comment
Кстати, не могли бы вы мне еще раз помочь? Обратный вызов здесь вообще не вызывается. Я жду, но ничего не происходит - person Mike_Device; 07.01.2015
comment
Вам нужно прочитать документы. Вы не проверяете возвращаемое значение. Или вызов GetLastError. - person David Heffernan; 07.01.2015
comment
функция возвращает 1, а GetLastError -- 0. Не могу понять, в чем проблема - person Mike_Device; 07.01.2015