Могу ли я использовать libcurls CURLOPT_WRITEFUNCTION с лямбда-выражением C ++ 11?

Я пытался использовать лямбда-выражение C ++ 11 с CURLOPT_WRITEFUNCTION, но программа вылетает во время выполнения с нарушением прав доступа. Я не уверен, как это сделать, из-за недостаточного знания C ++ 11, но, возможно, у кого-то есть идея, как это сделать.

Функция:

#ifndef CURL_GET_H
#define CURL_GET_H

#include <curl/curl.h>
#include <curl/easy.h>
#include <vector>
#include <string>

std::vector<std::string> curl_get(const char* url)
{
    CURL *curl;
    CURLcode res;

    std::vector<std::string> content;
    auto curl_callback = [](void *ptr, size_t size, size_t nmemb, void *stream) -> size_t {
        // does nothing at the moment due to testing...
        return size * nmemb;
    };

    curl = curl_easy_init();
    if (curl)
    {
        curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/aaa.txt");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_callback);
        res = curl_easy_perform(curl);
        curl_easy_cleanup(curl);
    }

    return content;
}

#endif // CURL_GET_H

Ошибка:

Unbehandelte Ausnahme bei 0x000000cc в lpip_dl.exe: 0xC0000005: Zugriffsverletzung bei Position 0x00000000000000cc.

(Нарушение прав доступа в позиции 0x00000000000000cc)

Происходит, когда curl хочет использовать обратный вызов:

wrote = data->set.fwrite_func(ptr, 1, len, data->set.out);
-121 --- 1258121 Безопасна ли эта реализация Blocking Queue? Я пытаюсь реализовать очередь, которая блокирует операцию Pop, если она пуста, и разблокирует, как только добавляется новый элемент. Боюсь, у меня может быть какое-то состояние гонки; Я попытался взглянуть на некоторые ...

Я пытаюсь реализовать очередь, которая блокирует операцию Pop, если она пуста, и разблокирует, как только вводится новый элемент.Боюсь, у меня может быть какое-то состояние гонки; Я попытался найти другую реализацию, но большинство из них было сделано в .NET, а несколько обнаруженных мною C ++ слишком сильно зависели от других библиотечных классов.

template <class Element>
class BlockingQueue{
    DRA::CommonCpp::CCriticalSection    m_csQueue;
    DRA::CommonCpp::CEvent              m_eElementPushed;
    std::queue<Element>                 m_Queue;
public:
    void Push( Element newElement ){
        CGuard g( m_csQueue );
        m_Queue.push( newElement );
        m_eElementPushed.set();
    }
    Element Pop(){
        {//RAII block
            CGuard g( m_csQueue );
            bool wait = m_Queue.empty();
        }
        if( wait )
            m_eElementPushed.wait();
        Element first;
        {//RAII block
            CGuard g( m_csQueue );
            first = m_Queue.front();
            m_Queue.pop();
        }
        return first;
    }
};

Требуются некоторые пояснения:

  • CCriticalSection - это оболочка для Критический раздел Windows, методы Enter и Leave являются частными, а CGuard - его единственный друг
  • CGuard - это RAII-оболочка для CCriticalSection, входит в критический раздел в конструкторе, оставляет его в деструкторе
  • CEvent - это оболочка для события Windows, wait использует функцию WaitForSingleObject
  • Я не возражаю, что элементы передаются по значению, это небольшие объекты
  • Я не могу использовать Boost, только вещи Windows (как я уже делал с CEvent и CGuard)

Боюсь, что при использовании Pop () может возникнуть странный сценарий состояния гонки. Как вы думаете, ребята?

ОБНОВЛЕНИЕ : Поскольку я работаю над Visual Studio 2010 (.NET 4.0), я в конечном итоге использовал класс unbounded_buffer, предоставляемый средой выполнения C ++. Конечно, я обернул его в класс с использованием идиомы «Указатель на реализацию» (Chesire Cat) на тот случай, если мы решим изменить реализацию или нам потребуется перенести этот класс в другую среду

5
задан dario_ramos 8 July 2011 в 14:36
поделиться