2014-02-15 2 views
0

Я реализую этот код, но получаю сообщение об ошибке.C2664 Невозможно преобразовать параметр

http://curl.haxx.se/libcurl/c/ftpupload.html

Ошибка в этом кусочке кода.

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream) 
{ 
    curl_off_t nread; 
    /* in real-world cases, this would probably get this data differently 
    as this fread() stuff is exactly what the library already would do 
    by default internally */ 
    size_t retcode = fread(ptr, size, nmemb, stream); 

    nread = (curl_off_t)retcode; 

    fprintf(stderr, "*** We read %" CURL_FORMAT_CURL_OFF_T 
      " bytes from file\n", nread); 
    return retcode; 
} 

Ошибки ...

IntelliSense: argument of type "void *" is incompatible with parameter of type "FILE *" 

и

Error C2664: 'fread' : cannot convert parameter 4 from 'void *' to 'FILE *' 

Любые советы будут полезны. Я не понимаю, почему мы передали поток void * в функцию. Что это вообще значит? Указатель на пустоту?

Это называется здесь.

/* we want to use our own read function */ 
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback); 

CURL API

CURLOPT_READFUNCTION

передать указатель на функцию, которая соответствует следующий прототип: функции size_t (Недействительными * PTR, size_t размера, size_t nmemb, аннулируются * UserData); Эта функция вызывается libcurl, как только она должна читать данные, чтобы отправить ее партнеру. Область данных, обозначенная указателем ptr, может быть заполнена не более, чем размер, умноженный на нм число байтов. Ваша функция должна вернуть фактическое количество байтов , которые вы сохранили в этой области памяти. Возврат 0 приведет к выходу в конец файла в библиотеку и остановке текущей передачи.

Если остановить текущую передачу по возвращении 0 «до зрело» (т.е. прежде чем сервер ожидал, например, когда вы сказали, что вы будете загружать г N байт и вы загружаете меньше, чем N байт), вы можете что сервер «зависает», ожидая, пока остальная часть данных не появится.

Считанные обратного вызова может возвращать CURL_READFUNC_ABORT немедленно прекратить текущую операцию , что приводит к ошибке CURLE_ABORTED_BY_CALLBACK кода от передачи (добавлено в 7.12.1)

От 7.18.0, функция может возвращать CURL_READFUNC_PAUSE, который то приведет к чтению из этого соединения, чтобы сделать паузу. См. curl_easy_pause (3) для получения дополнительной информации.

ошибка: при выполнении загрузки TFTP, вы должны вернуть точное количество данных, которая хочет обратный вызов, или оно будет считаться окончательным пакетом на стороне сервера и передача закончится там.

Если вы установите для этого указателя обратного вызова значение NULL или вообще не устанавливаете его, будет использоваться внутренняя функция чтения по умолчанию . Он делает fread() на FILE * userdata с CURLOPT_READDATA.

Я немного из глубины.

+0

'fread' принимает' FILE * 'как его ** ** четвертый аргумент,' 'недействительным * не совпадает. Предполагая, что аргумент 'stream' был' FILE * 'перед передачей его параметру, вам нужно его использовать:' fread (..., (FILE *) stream) ' – 0x499602D2

+0

@ 0x499602D2 на самом деле, [' fread() '] (http://en.cppreference.com/w/c/io/fread) принимает файл как * последний * параметр; не первый. Очевидно, что разрешение на показ правильное; просто переместите его = P. – WhozCraig

+0

@WhozCraig Упс! Спасибо что подметил это. Позвольте мне это исправить. :) – 0x499602D2

ответ

0

fread принимает FILE* в качестве своего четвертого аргумента, void* не соответствует. Предполагая, что аргумент потока был FILE* перед передачей его в параметр, вам нужно бросить его:

fread(..., (FILE*)stream); 

BTW reinterpret_cast более семантически подходит для этой задачи:

fread(..., reinterpret_cast<FILE*>(stream)); 

void* является общий тип указателя, который можно преобразовать в любой другой тип указателя.

0

Если ваша программа была написана на C, тогда код будет действителен, поскольку в C тип void * может быть неявно преобразован в указатель любого типа. Однако C++ не позволяет преобразовать неявно void * в указатель любого другого типа. Поэтому вам нужно явно указать тип того, что вы хотите преобразовать объект типа void *

Вы можете использовать либо литье в стиле C, либо литье в стиле C++. Например

size_t retcode = fread(ptr, size, nmemb, (FILE *)stream); 

или

size_t retcode = fread(ptr, size, nmemb, reinterpret_cast< FILE *>(stream)); 
Смежные вопросы