简体   繁体   中英

libcurl WriteMemoryCallback method don't work on iOS

I use libcurl to request data from my server.But the WriteMemoryCallback method don't work successfully. My operating system is iOS, libcurl's version is 7.40.0. These are my codes:

struct ResultStruct {
    char *memory;
    char *cookie_list;
    char *session_id;
};

struct MemoryStruct {
    char *memory;
    size_t size;
};

static size_t WriteMemoryCallback(char *contents, size_t size, size_t nmemb, struct MemoryStruct *userp)
{
    size_t realsize = size * nmemb;
    userp->memory = contents;
    if(userp->memory == NULL) {
        /* out of memory! */
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }
    return realsize;
}

curl_slist * get_cookies(CURL *curl)
{
    CURLcode res;
    struct curl_slist *cookies;
    printf("Cookies, curl knows:\n");
    res = curl_easy_getinfo(curl, CURLINFO_COOKIELIST, &cookies);
    if (res != CURLE_OK) {
        fprintf(stderr, "Curl curl_easy_getinfo failed: %s\n", curl_easy_strerror(res));
        exit(1);
    }
    return cookies;
}

char *get_comment(char *url)
{
    CURL *curl;
    CURLcode res;
    struct MemoryStruct *chunk = new struct MemoryStruct;
    chunk->memory = new char[2000];
    curl_global_init(CURL_GLOBAL_ALL);
    curl = curl_easy_init();
    if(curl) {
        curl_easy_setopt(curl, CURLOPT_URL, url);
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, chunk);
        curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "");
        curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
        res = curl_easy_perform(curl);
        if(res != CURLE_OK)
            fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
        curl_easy_cleanup(curl);
    }
//    curl_global_cleanup();
    std::cout << "------------------------------------------" << std::endl;
    std::cout << chunk->memory << std::endl;
    char *result = new char[2000];
    result = chunk->memory;
//    delete chunk->memory;
    delete chunk;
    std::cout << "******************************************" << std::endl;
    std::cout << result << std::endl;
    std::cout << "------------------------------------------" << std::endl;
    return result;
}

I have set a break point in the method WriteMemoryCallback, and I found that param contents contain the data that I need. But I set a break point in the method get_comment, I found that the param chunk lost some data. I don't know how to fix the bug.I don't find the error.I need help.

I strongly recommend you use NSURLSession rather than libcurl on iOS.

However, the issue here is that WriteMemoryCallback is called multiple times as libcurl receives data. You're supposed to aggregate the data you receive from those multiple calls, but you don't, you just set userp->memory to point to contents (which is a bad idea, as you're at least supposed to copy it, contents is not guaranteed to still contain the relevant data once the callback returns).

You need to allocate memory and append the newly received data in WriteMemoryCallback .

Or use NSURLSession : dataTaskWithURL:completionHandler will do all of that for you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM