我对c ++很陌生,而且我正在使用libcurl发出一个http请求并返回一个包含响应内容的字符串。
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)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
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)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)
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)" (?_Debug_message@std@@YAXPB_W0I@Z)
它似乎是一些库的问题,我尝试添加“msvcrtd.lib”,我仍然得到上面的错误以及其他新错误。
答案: 我将运行时库从多线程(/ MT)更改为多线程调试DLL(/ MDd)。
答案 0 :(得分:1)
您需要下载并编译源代码才能获取DLL / Library文件。我有与VS 2005下载的二进制版本类似的调试和链接问题。确保在编译器选项中包含头和库路径并链接libcurl.dll等,只需将其放在工作目录或system32文件夹中。 / p>
答案 1 :(得分:0)
std :: string通常不应该是以二进制形式(对象,静态库或DLL)分发的库的公共接口的一部分。但是libcurl是非常聪明的设计,可能std :: string支持由include文件提供(没关系),它在调用库之前将事物转换为可移植格式。
我认为您只需要小心将调试版本与libcurl的调试版本链接,并使用发行版本构建版本。否则你的程序的一部分需要msvcrt.lib而部分需要msvcrtd.lib,如果你试图同时使用它们就会发生冲突。
编辑回应提问者的评论:
编译/构建工具栏中有一个下拉组合框,可让您在Debug和Release配置之间进行选择。
此外,项目属性中的链接器“其他输入”设置可以具有不同的“调试”和“释放”值。可能调试版本应该使用“libcurld.lib”和发行版本“libcurl.lib”,但不是每个人都遵循相同的约定。
如果您将.lib文件添加到项目中而不是将其列在链接选项中,您仍然可以通过添加两个变体并相应地设置“从构建中排除此文件”来执行此操作。但这看起来很丑陋,会让在项目上工作的其他人感到困惑。我会在项目属性中使用链接器选项。
答案 2 :(得分: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 成员中。 告诉我它是否对你有用!