2016-08-05 24 views
0

Ich habe meinen Kopf darüber stundenlang kratzen, ich versuche, meine Struktur von CURLINFO_PRIVATE zugreifen, aber gcc scheint es nicht als eine Struktur zu erkennen: esWie Zugriff auf Struktur mit CURLINFO_PRIVATE in libcurl?

10-at-a-time.c: In function 'main': 
10-at-a-time.c:148:48: error: request for member 'size' in something not a structure or union 
printf("%lu bytes retrieved\n", (long)chunk->size); 
              ^
10-at-a-time.c:152:15: error: request for member 'memory' in something not a structure or union 
free(chunk->memory); 

In der Libcurl Dokumentation sagt Es gibt einen char-Zeiger zurück: https://curl.haxx.se/libcurl/c/CURLINFO_PRIVATE.html

Soweit ich verstanden habe, sollte ich in der Lage sein, diesen Zeiger mit der "->" Syntax zu dereferenzieren und die Struktur Instanz zu bekommen. Aber das scheint nicht zu funktionieren.

Hier ist mein Code, ich hoffe, es ist leicht zu verstehen: btw

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <errno.h>  

#include <curl/multi.h>  

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

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) { 
    size_t realsize = size * nmemb; 
    struct MemoryStruct *mem = (struct MemoryStruct *)userp; 

    mem->memory = realloc(mem->memory, mem->size + realsize + 1); 
    if(mem->memory == NULL) { 
     /* out of memory! */ 
     printf("not enough memory (realloc returned NULL)\n"); 
     return 0; 
    } 

    memcpy(&(mem->memory[mem->size]), contents, realsize); 
    mem->size += realsize; 
    mem->memory[mem->size] = 0; 

    return realsize; 
}  

static const char *urls[] = { 
    "http://www.microsoft.com", 
    "http://www.opensource.org", 
    "http://www.google.com", 
    "http://www.bbc.co.uk", 
    "http://www.newslink.org", 
    "http://www.un.org", 
    "http://www.news.com", 
    "http://www.cnn.com", 
    "http://www.wikipedia.org", 
    "http://www.dell.com", 
    "http://www.hp.com", 
    "http://www.cert.org", 
    "http://www.mit.edu", 
    "http://www.nist.gov", 
    "http://www.ebay.com", 
    "http://www.playstation.com", 
    "http://www.uefa.com", 
    "http://www.ieee.org", 
    "http://www.apple.com", 
    "http://www.symantec.com" 
}; 

#define count sizeof(urls)/sizeof(char*) 

static void init(CURLM *cm, int i) 
{ 
    CURL *eh = curl_easy_init();  

    struct MemoryStruct chunk; 

    chunk.memory = malloc(1); /* will be grown as needed by the realloc above */ 
    chunk.size = 0; /* no data at this point */  

    curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 
    curl_easy_setopt(eh, CURLOPT_WRITEDATA, (void *)&chunk); 
    curl_easy_setopt(eh, CURLOPT_HEADER, 0L); 
    curl_easy_setopt(eh, CURLOPT_URL, urls[i]); 
    curl_easy_setopt(eh, CURLOPT_PRIVATE, (void *)&chunk); 
    curl_easy_setopt(eh, CURLOPT_VERBOSE, 0L); 
    curl_multi_add_handle(cm, eh); 
} 

int main(void) 
{ 
    int bots = 10;  

    if (count < bots) { 
     bots = count; 
    }  

    CURLM *cm; 
    CURLMsg *msg; 
    long L; 
    struct timeval timeout; 
    unsigned int current = 0;  

    int msg_queue = -1; 
    int handles = -1; 
    int maxfd = -1;  

    fd_set fdread; 
    fd_set fdwrite; 
    fd_set fdexcep;  

    curl_global_init(CURL_GLOBAL_ALL); 
    cm = curl_multi_init();  

    curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)bots); 

    for (current = 0; current < bots; ++current) { 
     init(cm, current); 
    } 

    while (handles) { 
     curl_multi_perform(cm, &handles); 

     if (handles) { 
      FD_ZERO(&fdread); 
      FD_ZERO(&fdwrite); 
      FD_ZERO(&fdexcep); 

      if (curl_multi_fdset(cm, &fdread, &fdwrite, &fdexcep, &maxfd)) { 
       fprintf(stderr, "E: curl_multi_fdset\n"); 
       return EXIT_FAILURE; 
      } 

      if (curl_multi_timeout(cm, &L)) { 
       fprintf(stderr, "E: curl_multi_timeout\n"); 
       return EXIT_FAILURE; 
      }  

      if (L == -1) { 
       L = 100; 
      } 

      if (maxfd == -1) { 
       sleep((unsigned int)L/1000); 
      } 
      else { 
       timeout.tv_sec = L/1000; 
       timeout.tv_usec = (L % 1000) * 1000; 

       if (0 > select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout)) { 
        fprintf(stderr, "E: select(%i,,,,%li): %i: %s\n", maxfd + 1, L, errno, strerror(errno)); 
        return EXIT_FAILURE; 
       } 
      } 
     } 

     while ((msg = curl_multi_info_read(cm, &msg_queue))) { 
      if (msg->msg == CURLMSG_DONE) { 
       char *chunk; 
       CURL *e = msg->easy_handle; 
       curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &chunk); 
       fprintf(stderr, "R: %d - %s\n", msg->data.result, curl_easy_strerror(msg->data.result));  

       printf("%lu bytes retrieved\n", (long)chunk->size); 

       curl_multi_remove_handle(cm, e); 
       curl_easy_cleanup(e); 
       free(chunk->memory); 
      } 
      else { 
       fprintf(stderr, "E: CURLMsg (%d)\n", msg->msg); 
      }  

      if (current < count) { 
       init(cm, current++); 
       handles++; 
      } 
     } 
    } 

    curl_multi_cleanup(cm); 
    curl_global_cleanup(); 

    return EXIT_SUCCESS; 
} 

Ich bin neu in C.

Antwort

0

Stellen Sie den privaten Zeiger:

ptr = [something]; 
curl_easy_setopt(curl, CURLOPT_PRIVATE, ptr); 

Extrahieren Sie die Zeiger wieder vom Griff wurde eingestellt in:

curl_easy_getinfo(curl, CURLINFO_PRIVATE, &ptr); 

In Ihrem Fall, wenn Sie den Mauszeiger wieder extrahieren müssen Sie sicherstellen, Sie haben es als den richtigen Strukturzeiger und nicht nur eine char *. Wie vielleicht:

struct MemoryStruct *chunk; 
curl_easy_getinfo(curl, CURLINFO_PRIVATE, &chunk); 

... als dann können Sie auf die Struktur und ihre Felder zugreifen.

+0

Vielen Dank Daniel, das funktioniert perfekt. Ich dachte nicht, dass es so einfach wäre :) – sasha