2010-03-07 60 views
0

我很新的C++和我使用的libcurl使一個HTTP請求,並取回與響應的內容的字符串。STD字符串問題的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; 
} 

運行上面的代碼(與VS2005)後,我得到這個錯誤:

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]) 

它看起來像它的一些庫問題,我嘗試添加「MSVCRTD.LIB」我仍然得到上面的錯誤與其他新錯誤。

答案: 我將運行時間庫從多線程(/ MT)更改爲多線程調試DLL(/ MDd)。

回答

0

的std :: string一般不應分佈以二進制形式(對象,靜態庫,或DLL)文庫的公共接口的一部分。但是libcurl的設計非常智能,可能std :: string支持是由包含文件提供的(沒關係),它在調用庫之前將其轉換爲可移植的格式。

我認爲你需要小心鏈接你的調試版本與libcurl中的調試版本,併發布版本一起發佈的版本。否則你的程序的一部分需要msvcrt.lib,部分需要msvcrtd.lib,如果你嘗試同時使用它們,它們會發生衝突。

編輯迴應提問者的評論:

有編譯/構建工具欄中的下拉組合框中,讓您調試之間進行選擇和Release配置。

此外,鏈接器「其他輸入」項目屬性設置可以對調試和發佈不同的值。可能調試版本應該使用「libcurld.lib」和發佈版本「libcurl.lib」,但不是每個人都遵循相同的約定。

如果您添加的.lib文件到您的項目,而不是在鏈接選項上市了,你仍然可以通過添加兩種變體和設置「排除從構建此文件」適當地做到這一點。但是,這看起來很醜陋,並會混淆項目工作的其他人。我會在項目屬性中使用鏈接器選項。

+0

如何鏈接我的dbug構建?使用visual studio 2005 .. – shaimagz 2010-03-07 05:39:28

+0

如何將std :: string更改爲char *? – shaimagz 2010-03-07 05:53:07

+0

不知道爲什麼std :: string不應該是公共接口的一部分。另一種選擇是char *,它有自己的問題。 – Ben 2010-03-07 05:55:03

1

你需要下載和編譯源代碼,讓您的DLL /庫文件。我爲VS 2005下載的二進制版本有類似的調試和鏈接問題。請確保在編譯器選項中包含頭文件和庫路徑,並將libcurl.dll等鏈接到工作目錄或system32文件夾中。

+0

謝謝,但我已經有與libcurl.lib和libcurl.dll文件和包括鏈接的程序。我試圖把它放在system32文件夾中,但仍然沒有。 – shaimagz 2010-03-07 06:08:09

+0

您是否下載並遵守源代碼並試圖鏈接這些文件?我建議你下載並使用「依賴walker」來確定你的代碼沒有鏈接到哪個DLL,或者如果它們是不同版本或可能已損壞。 – cpx 2010-03-07 06:29:33

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(); 
} 

這裏就是你需要做的請求......因爲你可以看到代碼,你必須創建一個名爲WriteMemoryCallback靜態方法被編碼如下:

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; 
} 

此解決方案完全適合我,並將信息存儲在chunk.memory成員。 告訴我它是否對你有用!