2010-03-07 6 views
0

Je suis assez nouveau sur C++ et j'utilise libcurl pour faire une requête http et récupérer une chaîne avec le contenu de la réponse.Problème de chaîne std avec libcurl - C++

size_t write_to_string(void *ptr, size_t size, size_t count, void *stream) { 
    ((std::string*)stream)->append((char*)ptr, 0, size*count); 
    return size*count; 
} 

int main(void) { 

    CURL *curl; 
    CURLcode res; 
    curl = curl_easy_init(); 

    if (curl) { 
    curl_easy_setopt(curl, CURLOPT_URL, "http://www.browsarity.com/"); 

    std::string response; 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_to_string); 
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response); 

    res = curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 

    // The "response" variable should now contain the contents of the HTTP response 
    } 
    return 0; 
} 

après l'exécution du code ci-dessus (avec VS2005) Je reçois cette erreur:

1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" ([email protected][email protected]@@[email protected]) 
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" ([email protected][email protected]@@[email protected]) 
1>libcpmtd.lib(stdthrow.obj) : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function "void __cdecl std::_Debug_message(wchar_t const *,wchar_t const *,unsigned int)" ([email protected]@@[email protected]) 

son semble comme son problème avec quelques bibliothèques et j'ai essayé d'ajouter « MSVCRTD.LIB » et je reçois encore l'erreur ci-dessus avec de nouvelles erreurs supplémentaires.

Réponse: J'ai changé la bibliothèque d'exécution de Multi-Threaded (/ MT) en DLL de débogage multi-thread (/ MDd).

Répondre

0

std :: string ne devrait généralement pas faire partie d'une interface publique d'une bibliothèque distribuée sous forme binaire (objet, librairie statique ou DLL). Mais libcurl est assez intelligemment conçu, probablement le support std :: string est fourni par un fichier include (c'est ok) qui convertit les choses dans un format portable avant d'appeler dans la bibliothèque.

Je pense que vous devez juste faire attention à lier vos versions de débogage avec la version de débogage de libcurl, et votre version se construit avec la version finale. Sinon, une partie de votre programme veut msvcrt.lib et une partie veut msvcrtd.lib, et elles sont en conflit si vous essayez d'utiliser les deux à la fois.

EDIT en réponse au commentaire du demandeur:

Il y a une zone de liste déroulante déroulant dans la barre d'outils de compilation/build, qui vous permet de choisir entre les configurations de débogage et Release.

En outre, le paramètre "Entrées supplémentaires" de Linker dans les propriétés du projet peut avoir des valeurs différentes pour le débogage et la libération. La version de débogage devrait probablement utiliser "libcurld.lib" et la version "libcurl.lib", mais tout le monde ne suit pas la même convention.

Si vous avez ajouté le fichier .lib à votre projet au lieu de le répertorier dans les options de lien, vous pouvez toujours le faire en ajoutant les deux variantes et en définissant "Exclure ce fichier de la construction" de manière appropriée. Mais cela a l'air moche et va dérouter toute autre personne qui travaille sur le projet. J'utiliserais les options du Linker dans les propriétés du projet.

+0

Comment lier mes builds dbug? en utilisant Visual Studio 2005 .. – shaimagz

+0

qu'en est-il de changer la chaîne std :: en char *? – shaimagz

+0

Vous ne savez pas pourquoi std :: string ne devrait pas faire partie d'une interface publique. L'alternative est char *, qui a ses propres problèmes. – Ben

1

Vous devez télécharger et compiler le code source pour obtenir vos fichiers DLL/bibliothèque. J'ai eu les mêmes problèmes de débogage et de liaison avec la version binaire que j'ai téléchargée pour VS 2005. Assurez-vous d'inclure les chemins d'en-tête et de bibliothèque dans les options du compilateur et de lier le libcurl.dll etc.

+0

Merci, mais j'avais déjà le programme lié avec les fichiers libcurl.lib et libcurl.dll et les inclus. J'ai essayé de le mettre dans le dossier system32 mais toujours rien. – shaimagz

+0

Avez-vous téléchargé et respecté le code source et essayé de créer des liens avec ces fichiers? Je vous suggère de télécharger et d'utiliser le "dépendant de la dépendance" pour déterminer quelles DLL votre code n'est pas lié ou si elles sont d'une version différente ou peut-être corrompue. – cpx

0
//login 
    curl_easy_setopt(handle,CURLOPT_USERNAME,username); 
    curl_easy_setopt(handle,CURLOPT_PASSWORD,password); 

    m_popsAccount = "pop3s://pop.gmail.com:995/"; //this URL only returns the list of emails with "[index] [size]" format 

    curl_easy_setopt(handle, CURLOPT_URL, m_popsAccount.c_str()); 
    curl_easy_setopt(handle, CURLOPT_USE_SSL, CURLUSESSL_ALL); 
    curl_easy_setopt(handle, CURLOPT_SSL_VERIFYPEER, 0); 
    curl_easy_setopt(handle, CURLOPT_SSL_VERIFYHOST, 0); 

    curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 
    curl_easy_setopt(handle, CURLOPT_VERBOSE, 1); 

    curl_easy_setopt(handle, CURLOPT_WRITEDATA, (void *)&chunk); 
    //some servers needs this validation 
    curl_easy_setopt(handle, CURLOPT_USERAGENT, "libcurl-agent/1.0"); 

    res = curl_easy_perform(handle); 

    if(res != CURLE_OK) 
    { 
     fprintf(stderr, "curl_easy_perform() failed: %s\n", 
      curl_easy_strerror(res)); 
    } 
    else 
    { 
     printf("%s\n",chunk.memory); //here is the information 
    } 

    if(chunk.memory) 
     free(chunk.memory); 
    /* always cleanup */ 

    curl_global_cleanup(); 
} 

ici est le code que vous devez faire la demande ... comme vous pouvez le voir, vous devez créer une méthode statique appelée WriteMemoryCallback qui est codé comme celui-ci:

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

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

    mem->memory = (char *)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; 
} 

Cette solution fonctionne parfaitement pour moi, et stocke l'information à l'intérieur chunk.memory membre. Dites-moi si c'était utile pour vous!