我使用http://ubuntuforums.org/showthread.php?t=781021作为如何编写c ++程序的指南,该程序使用libcurl检查网站并将文本下载到c ++应用程序。当我将代码复制到我的visual studio项目时,它只需稍加修改即可使用。但是,我试图将其转换为基于类的文件。
我创建了.h
和.cpp
个文件来运行查询。我之前没有意识到的是handle_data
不是一个典型的函数,因为它在Viewer.cpp的中途没有给出任何参数甚至()
。这就是上面的网站如何做到的,并且它有效,但我现在还不知道为什么或如何转换它。
有谁知道这里发生了什么或如何修复它? 谢谢!
Viewer.h:
#pragma once
#include <string>
#include "curl.h"
class Viewer
{
public:
Viewer(void);
~Viewer(void);
std::string view(std::string q);
private:
size_t handle_data(void *ptr, size_t size, size_t nmemb, void *stream);
std::string contents;
};
Viewer.cpp:
#include "stdafx.h"
#include "Viewer.h"
#include <iostream>
Viewer::Viewer(void)
{
std::cout << "ViewerCreated!\n";
}
Viewer::~Viewer(void)
{
}
size_t Viewer::handle_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
int numbytes = size*nmemb;
// The data is not null-terminated, so get the last character, and replace
// it with '\0'.
char lastchar = *((char *) ptr + numbytes - 1);
*((char *) ptr + numbytes - 1) = '\0';
contents.append((char *)ptr);
contents.append(1,lastchar);
*((char *) ptr + numbytes - 1) = lastchar; // Might not be necessary.
return size*nmemb;
}
std::string Viewer::view(std::string q)
{
char* url = "www.google.com";
CURL* curl = curl_easy_init();
if(curl)
{
// Tell libcurl the URL
curl_easy_setopt(curl,CURLOPT_URL, url);
// Tell libcurl what function to call when it has data
curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,handle_data);
// Do it!
CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl);
if (res == 0)
std::cout << contents << std::endl;
else
std::cerr << "Error: " << res << std::endl;
}
return contents;
}
答案 0 :(得分:1)
您不应该替换您收到的块的最后一个字符。相反,您应该强制包含附加块的缓冲区在数据结束后才有'\ 0'。这种方式可以打印,但是如果要将其存储在文件中,则应该只写下你收到的字节。
这一直对我有用:
struct MemoryStruct chunk;
chunk.memory=NULL;
chunk.size = 0;
...
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
回调:
struct MemoryStruct {
char *memory;
size_t size;
};
static void *myrealloc(void *ptr, size_t size)
{
if(ptr)
return realloc(ptr, size);
else
return malloc(size);
}
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
{
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)data;
mem->memory = (char *)myrealloc(mem->memory, mem->size + realsize + 1);
if (mem->memory) {
memcpy(&(mem->memory[mem->size]), ptr, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
}
return realsize;
}
答案 1 :(得分:0)
handle_data用作curl_easy_setopt的参数。这意味着你必须编写handle_data在接收下一个数据块时所做的事情(假设数据块是curl将为你做的事情)。
答案 2 :(得分:0)
handle_data
作为回调函数传递给curl_easy_setopt
,当有可用数据时,它将调用它。因此,handle_data
必须被称为静态函数(即,没有接收到对象指针,因为cURL
没有一个)。但是,您并未将其声明为静态。即使您这样做,也会访问其中的contents
,这是无效的。