VS2013 ERROR 0xC0000005:使用libcurl时

时间:2015-05-16 18:11:11

标签: c++ visual-studio libcurl

我尝试使用libcurl(http://curl.haxx.se/libcurl/c/)从网上下载数据,并将这些数据存储在txt文件中,这是我的代码:

// CLASS SinaStk

size_t save_data(char *buffer, size_t size, size_t nmemb, FILE* userdata){


locale loc = std::locale::global(std::locale("")); //TRY TO OPEN FILE WITH CHINESE

userdata = fopen(fpath.c_str(), "w");
if (userdata == NULL)
printf("File not open!\n");
locale::global(loc);
size_t writelen=size * nmemb;

fwrite(buffer, size, nmemb, userdata);

return writelen;
};

virtual void downloadUrl()   
{
    CURL* stkCURL=NULL;
    CURLcode res;
    FILE * fp=NULL;

    curl_global_init(CURL_GLOBAL_WIN32);  
    stkCURL = curl_easy_init();    

    curl_easy_setopt(stkCURL, CURLOPT_URL,"http://hq.sinajs.cn/list=s_sh000001"); 
    curl_easy_setopt(stkCURL, CURLOPT_WRITEFUNCTION, &SinaStk::save_data); 
    curl_easy_setopt(stkCURL, CURLOPT_WRITEDATA,fp);
    res=curl_easy_perform(stkCURL);                  //<-STOP!!!!

    fclose(fp);
    curl_easy_cleanup(stkCURL);
    curl_global_cleanup();
    return;
};

当我调试我的代码时,它总是停止然后跳转到xstring:

    size_type size() const _NOEXCEPT
    {   // return length of sequence
      return (this->_Mysize);                  // <-STOP!!! 
    }

0xC0000005:访问冲突读取位置0x0000009E

我差不多一周都不知道这个问题。我很沮丧,我问周围的人,没有人知道为什么。

感谢阅读,我真的很困惑。

=============

问题解决了!谢谢你们!现在我的代码是:

//CLASS StkApiInfo
size_t writeData(char* buffer, size_t size, size_t nmemb){
    if (stkFile.is_open()){
        stkFile.close();
        stkFile.clear();
    };
    fpath = "D:\\Code\\代码\\数据文件\\" + fname + ".txt";
    stkFile.open(fpath.c_str(), ios::out);
    //if (stkFile.is_open())
    cout << buffer<<size<<nmemb;
    stkFile << buffer<<endl;
    stkFile.close();
    stkFile.clear();
    return size*nmemb;
};

//CLASS SinaStk : public StkApiInfo
static size_t save_data(char *buffer, size_t size, size_t nmemb, void* userdata){

    SinaStk* self = (SinaStk*)userdata;
    return self->writeData(buffer, size, nmemb);
};

virtual void downloadUrl()  
{
    CURL* stkCURL = NULL;
    CURLcode res;
    curl_global_init(CURL_GLOBAL_WIN32); 
    stkCURL = curl_easy_init();  
    if (stkCURL)
    {
        curl_easy_setopt(stkCURL, CURLOPT_URL, stkUrl.c_str());
        curl_easy_setopt(stkCURL, CURLOPT_WRITEFUNCTION, &SinaStk::save_data);
        curl_easy_setopt(stkCURL, CURLOPT_WRITEDATA, this);
        res = curl_easy_perform(stkCURL);
        //if (res != CURLE_OK)
        curl_easy_cleanup(stkCURL);
        curl_global_cleanup();
    }

    return;
};

1 个答案:

答案 0 :(得分:1)

使用CURLOPT_WRITEFUNCTION参数传递的回调应该是write_callback类型(具有该签名),因此不能是非静态类方法。通常的解决方法是将回调定义为非成员或静态方法,并将this作为参数传递:

static size_t save_data(char *buffer, size_t size, size_t nmemb, void* userdata)
{
    SinaStk* self = (SinaStk*) userdata;
    return self->doStuff(buffer, size, nmemb);
}

virtual void downloadUrl()   
{
    //...
    curl_easy_setopt(stkCURL, CURLOPT_WRITEFUNCTION, &SinaStk::save_data); 
    curl_easy_setopt(stkCURL, CURLOPT_WRITEDATA, this);
    //...
}

如果您需要访问其他数据(例如示例中的FILE*),您可以将其存储为类字段,或者引入包含this和其他数据字段的临时结构,并将其作为地址传递为回调参数。