Dvejetainių libcurl atsakymų priėmimas į C++ std::string
Perduokite std::string kaip atgalinio iškvietimo kontekstą ir pridėkite aiškius baitų skaičius, kai su libcurl priimate dvejetainius duomenis.
Tarpinė serveris gali sėkmingai gauti HTML ir vis tiek sugadinti vaizdą, kai jį kopijuoja į C++ buferį. Prieš keisdami tarpinės serverio protokolą, patikrinkite priėmimo atgalinį iškvietimą ir objektą, perduodamą kaip jo kontekstą.
CURLOPT_WRITEDATA pateikia rodyklę į rašymo atgalinį iškvietimą. Be pasirinktinio atgalinio iškvietimo libcurl numatytasis rašytojas tikisi FILE *. Adresas, pavyzdžiui, &response, kur response yra std::string, turi prasmę tik tada, kai jūsų atgalinis iškvietimas konvertuoja tą kontekstą atgal į numatytą tipą.
static size_t receive(char* data, size_t size,
size_t count, void* context) {
const size_t bytes = size * count;
auto* body = static_cast<std::string*>(context);
try {
body->append(data, bytes);
} catch (...) {
return 0;
}
return bytes;
}Užregistruokite abi puses paprastame apdoroje, naudojamame perdavimui:
std::string response;
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, receive);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response);Iškvietimas append naudoja pateiktą baitų skaičių. Atgalinio iškvietimo duomenys nėra baigiami nuliu, o vaizde gali būti nulinių baitų; matavimas su strlen prarastų dalį turinio. Atsakymas taip pat gali atkeliauti per daug skirtingo dydžio iškvietimų.
Sunaudotų baitų skaičiaus grąžinimas priima dalį. Kito skaičiaus grąžinimas nutraukia perdavimą rašymo klaida. Išimčių apsauga neleidžia atminties paskirstymo klaidai ištrūkti už C atgalinio iškvietimo ribos; iškvietėjas vis tiek turi patikrinti perdavimo rezultatą prieš laikydamas response užbaigtu failu.
Laikykite eilutę gyvą, kol perdavimas baigsis. Jei asinchroninis lizdo rašymas tada perduoda jos turinį, laikykite tuos baitus gyvus, kol ir tas rašymas baigsis. Dideliems atsakymams ribota srautinė tvarka yra geresnė už viso turinio kaupimą.