Bastian Temat założony przez niniejszego użytkownika |
Curlpp przypisywanie wyniku do zmiennej » 2017-08-27 09:58:12 Czesc, Pisze oto taką metode, która ma być parserem HTTP/HTTPS void KGrawler::parser( char * url ) { using namespace curlpp::options; try { curlpp::Cleanup myCleanup; curlpp::Easy myRequest; myRequest.setOpt < Url >( url ); myRequest.perform(); } catch( curlpp::RuntimeError & e ) { std::cout << e.what() << std::endl; } catch( curlpp::LogicError & e ) { std::cout << e.what() << std::endl; } }
W domyslnych ustawieniach curlpp::Easy:perform() wyrzyguje output na stdout. Aby zmienic do zachowanie z tego co czytam należy ustawić odpowiednio curlpp::OptionTrait<void *, CURLOPT_WRITEDATA> Zatem probuje w taki sposób: void KGrawler::parser( char * url ) { using namespace curlpp::options; try { curlpp::Cleanup myCleanup; curlpp::Easy myRequest; std::string oput; curlpp::OptionTrait < void *, CURLOPT_WRITEDATA > myData( oput ); request.setOpt( myData ); myRequest.perform(); } catch( curlpp::RuntimeError & e ) { std::cout << e.what() << std::endl; } catch( curlpp::LogicError & e ) { std::cout << e.what() << std::endl; } }
Niestety słabo to rozumiem i dostaje błąd kompilacji: /home/grzempek/git/KGrawler/src/KGrawler.cpp|66|error: no matching function for call to ‘curlpp::OptionTrait<void*, (CURLoption)10001u>::OptionTrait(std::string&)’|
Ktoś wie jak to poprawnie zrobić? pzdr |
|
j23 |
» 2017-08-27 10:45:31 Przecież z treści błędu jasno wynika, że podajesz argument o niewłaściwym typie. Jakoś tak powinno być: curlpp::WriteData myData( static_cast < void *>( & oput ) ); |
|
Bastian Temat założony przez niniejszego użytkownika |
» 2017-09-07 21:02:52 Hej, Program sie skompilował ale oczywiście nie działa poprawnie. Rozumiem, że na podstawie błędu wywioskowałeś, że powinienem zrobić tak: curlpp::OptionTrait < void *, CURLOPT_WRITEDATA > myData( static_cast < void *>( & oo ) );
Jeśli dobrze to czytam to jest to instancja klasy szablonowej curlpp::OptionTrait z argumentami szablonu w postaci wskaznika (void *) oraz stałej CURLOPT_DATA. Instancja klasy o nazwie myData() przyjmuje argumenty o takim typie jaki podaje w szablonie a więc void *, ale z racji tego ze chce przekazać std::string oo to trzeba użyć rzutowania czyli static_cast<void *>(& oo)) Prosze o potwierdzenie, że dobrze to rozumiem, bo ta składnia i sygnatury w C++ doprowadzają mnie do szaleństwa :) Druga sprawa jest taka, że program działa niepoprawnie Dostaje przy próbie zapisania Failed writing body (0 != 665)
Zgodnie z przykładem: https://github.com/jpbarrette/curlpp/blob/master/examples/example11.cpp...trzeba stworzyc callback i przekazac go do klasy curlpp::options::WriteFunctionCurlFunction
..tyle ze tam jest zapis outputu do pliku a ja chce zapisać w zmiennej do dalszej analizy. Jak widzicie dopiero raczkuje i potrzebna mi pomoc... |
|
j23 |
» 2017-09-08 12:02:26 Dobrze to rozumiesz. Użyłem curlpp::WriteData, żeby uprościć zapis. Druga sprawa jest taka, że program działa niepoprawnie |
Callback jakoś tak powinien wyglądać: size_t write_to_string_callback( char * ptr, size_t size, size_t nmemb, void * pstr ) { std::string * s = static_cast < std::string *>( pstr ); size *= nmemb; s->append( ptr, size ); return size; };
|
|
Bastian Temat założony przez niniejszego użytkownika |
» 2017-09-14 21:05:21 Zrobilem tak: size_t KGrawler::WriteToStringCallback( char * ptr, size_t size, size_t nmemb, void * pstr ) { std::string * s = static_cast < std::string *>( pstr ); size *= nmemb; s->append( ptr, size ); return size; }
void KGrawler::parser( char * url ) { std::cout << std::endl << std::endl; std::cout << url << std::endl; using namespace curlpp::options; try { curlpp::Cleanup myCleanup; curlpp::Easy myRequest; WriteFunctionCurlFunction myFunction( WriteToStringCallback ); std::string oo; curlpp::OptionTrait < void *, CURLOPT_WRITEDATA > myData( static_cast < void *>( & oo ) ); myRequest.setOpt( myFunction ); myRequest.setOpt( myData ); myRequest.setOpt < Url >( url ); myRequest.perform(); } catch( curlpp::RuntimeError & e ) { std::cout << e.what() << std::endl; } catch( curlpp::LogicError & e ) { std::cout << e.what() << std::endl; } }
Ale teraz rzyga: In member function ‘void KGrawler::parser(char*)’:| no matching function for call to ‘curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>::OptionTrait(<unresolved overloaded function type>)’| candidates are:| curlpp::OptionTrait<OptionType, opt>::OptionTrait() [with OptionType = long unsigned int (*)(char*, long unsigned int, long unsigned int, void*); CURLoption opt = (CURLoption)20011u]| candidate expects 0 arguments, 1 provided| curlpp::OptionTrait<OptionType, opt>::OptionTrait(typename curlpp::Option<OptionType>::ParamType) [with OptionType = long unsigned int (*)(char*, long unsigned int, long unsigned int, void*); CURLoption opt = (CURLoption)20011u; typename curlpp::Option<OptionType>::ParamType = long unsigned int (*)(char*, long unsigned int, long unsigned int, void*)]| no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘curlpp::Option<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*)>::ParamType {aka long unsigned int (*)(char*, long unsigned int, long unsigned int, void*)}’| curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>::OptionTrait(const curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>&)| no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘const curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>&’| curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>::OptionTrait(curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>&&)| no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>&&’| ||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
Przyznam szczerze, że teraz nie rozumiem, która metode wywoluje ze zlymi atrybutami: no matching function for call to ‘curlpp::OptionTrait<long unsigned int (*)(char*, long unsigned int, long unsigned int, void*), (CURLoption)20011u>::OptionTrait(<unresolved overloaded function type>)
|
|
Monika90 |
» 2017-09-15 09:23:07 WriteFunctionCurlFunction myFunction( WriteToStringCallback );
WriteToStringCallback to jest funkcja składowa klasy. Taką funkcję można wywołać, wtedy należy podać jej argumenty, albo pobrać jej adres, co wygląda tak & KGrawler::WriteToStringCallback . Ale WriteFunctionCurlFunction pewnie nie zadziała z funkcją składową. |
|
j23 |
» 2017-09-15 10:25:44 Zrób WriteToStringCallback metodą statyczną. |
|
Bastian Temat założony przez niniejszego użytkownika |
» 2017-09-20 20:54:12 WriteToStringCallback to jest funkcja składowa klasy. Taką funkcję można wywołać, wtedy należy podać jej argumenty, albo pobrać jej adres, co wygląda tak & KGrawler::WriteToStringCallback . Ale WriteFunctionCurlFunction pewnie nie zadziała z funkcją składową Rozumiem, że Twoim zdaniem nie można jej było zastosować jako metode klasy KGrawler?? A możesz napisać dlaczego tak uważasz? Po sugestii kolegi j23 program sie skompilował i callback działa poprawnie, ale dla dobrego zrozumienia chciałbym poznać Twoją opinie. Zrób WriteToStringCallback metodą statyczną. Program sie skompilowal i zdaje się ze działa poprawnie. Wybaczcie, że mam pytania, ale ucze się sam i nie mam kogo dopytywać... size_t KGrawler::WriteToStringCallback( char * ptr, size_t size, size_t nmemb, void * pstr ) { std::string * s = static_cast < std::string *>( pstr ); size *= nmemb; s->append( ptr, size ); return size; }
size_t KGrawler::WriteToStringCallback( char * ptr, size_t size, size_t nmemb, void * pstr ) Atrybuty tego callbacka pochodzą z nagłówków samego libcurla, to znalazłem typedef size_t( * curl_write_callback )( char * buffer, size_t size, size_t nitems, void * outstream );
std::string * s = static_cast < std::string *>( pstr ); Przypisujesz do wskaznika o typie std::string zrzutowaną na typ string wartość ze wskaźnika pstr Tego nie rozumiem. 'size' to wielkosc buffora danego odczytu a nmemb ? Ilosc znaków z buffora? Appendujesz do obiektu wskaznika na obiekt s typu std::string zawartosc buffora (dany odczyt http), a paramert size jest iloscią znaków, która ma appendować. A dlaczego nie wystarczy samo: Zgodnie z dokumentacja powinno appendować całą zawartosc 'prt' no nie ? |
|
« 1 » 2 |