2010-03-07 83 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成员。 告诉我它是否对你有用!