8

複数のファイルをダウンロードするプログラムを書いています(現時点では2つだけです)。コールバックを使用して、ダウンロードごとに進行状況バーを表示しようとしていProgressFunctionます。私が直面している問題は、2 つのファイルの進行状況を区別する方法がわからないことです。現在、この 2 つを切り替えています。さらにドキュメントを探してみましたが、サイトの API リンクが壊れているようで、いくつかの基本的な例以外にはあまりありません。

    //ProgressCalback
    double ProgressCallBack(double dltotal, double dlnow, double ultotal, double ulnow){
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%s\t%d\t%d\t%d\t%d\n", strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    };

    curlpp::options::ProgressFunction progressBar(ProgressCallBack);
    request1.setOpt(new curlpp::options::Url(url1));
    request1.setOpt(new curlpp::options::Verbose(false));
    request1.setOpt(new curlpp::options::NoProgress(0));
    request1.setOpt(progressBar);

コードのどの部分が関連するかは完全にはわかりません。ここでは、進行状況のコールバックに関連する部分を示します。どんな助けでも大歓迎です。

4

3 に答える 3

4

ここに、アイデアを表現するための汚い傷があります。

class CurlppProgress
{
  class Entry 
  {
  public:
    Entry( const CurlppProgress *owner );

    const CurlppProgress *owner;
    double dlTotal, dlNow, ulTotal, ulNow;

    void callback( double dltotal, double dlnow, double ultotal, double ulnow );
  };
  std::vector<Entry> entries;

  void print_progress() const;
  friend class Entry;
public:
  CurlppProgress();

  void AddEntry( curlpp::Easy *request );
};

CurlppProgress::Entry::Entry( const CurlppProgress *_owner )
  : owner( _owner )
  , dlNow()
  , dlTotal()
  , ulNow()
  , ulTotal()
{
}

void CurlppProgress::Entry::callback( double _dltotal, double _dlnow, double _ultotal, double _ulnow )
{
  dlNow = _dlnow;
  dlTotal = _dltotal;
  ulNow = _ulnow;
  ulTotal = _ultotal;
  owner->print_progress();
}

void CurlppProgress::AddEntry( curlpp::Easy *request )
{
  Entry newEntry( this );
  m_entries.push_back( newEntry );
  curlpp::types::ProgressFunctionFunctor progressFunctor(&m_entries.back(), &CurlppProgress::Entry::callback);
  request->setOpt(new curlpp::options::ProgressFunction(progressFunctor));

}

void CurlppProgress::print_progress() const
{
  double ulnow = 0.0;
  double ultotal = 0.0;
  double dlnow = 0.0;
  double dltotal = 0.0;
  for ( std::vector<Entry>::const_iterator i = entries.begin(), e = entries.end(); i != e; ++i )
  {
    ulnow += i->ulNow;
    ulTotal += i->ulTotal;
    dlnow += i->dlNow;
    dltotal += i->dlTotal;
  }

  // print progress here
}

ただし、使用する前に修正する必要があります(所有権を解決する必要があり、ベクターのバッファーの再割り当てによりクラッシュなどが発生します)が、アイデアが明確であることを願っています。

于 2011-10-12T21:47:39.933 に答える
2

免責事項: 私の C++ は錆びていて、以前は curlpp を使用したことがないため、以下のコードには多少の修正が必要になる場合があります。

コールバック関数で必要なのは、2 つのダウンロードを区別できるものです。curlpp ではそれができないため、代わりにファンクターを使用する必要があります。したがって、進行状況のコールバック用に、次のようなクラスを作成します。

class ProgressCallback
{
public:
    ProgressCallback(int index) : downloadIndex(downloadIndex)
    {
    }

    double operator()(double dltotal, double dlnow, double ultotal, double ulnow)
    {
       double progress = (dlnow/dltotal) * 100;
       std::ostringstream strs;
       float percent = floorf(progress * 100) / 100;
       strs << percent;
       printf("%d: %s\t%d\t%d\t%d\t%d\n", downloadIndex,
              strs.str().c_str(),dltotal, dlnow, ultotal, ulnow);
       return 0;
    }

private:
    int downloadIndex;
};

これで、次のように使用できるはずです。

ProgressCallback callback1(1);
curlpp::options::ProgressFunction progressBar(callback1);

もちろん、これらのコールバック ファンクターの寿命について考える必要があります。おそらくそれらをスタックに残すのは悪い考えです。


編集:これを行う簡単な方法があるようです。ではutilspp/functor.h、make_functor() と BindFirst() の 2 つのテンプレート関数が定義されています。したがって、次のようにdownloadIndexパラメーターを単純に追加できますProgressCallback

double ProgressCallBack(int dlIdx,
                        double dltotal, double dlnow,
                        double ultotal, double ulnow);

そして、次のように登録します。

curlpp::options::ProgressFunction
    progressBar(BindFirst(make_functor(ProgressCallback), 1));
于 2011-10-12T21:36:30.240 に答える
0

CURLOPT_PROGRESSDATAコア libcurl ライブラリを使用すると、オプションを介して進行状況コールバックにユーザー定義のデータを渡すことができます。コールバックには、void *clientpパラメータの前に追加のパラメータがありdouble dltotalます。

typedef int (*curl_progress_callback)(void *clientp,
                                      double dltotal,
                                      double dlnow,
                                      double ultotal,
                                      double ulnow);

ただし、cURLpp の最新のソース コードを見ると、CURLOPT_PROGRESSDATAオプションへのアクセスは公開されていないようです。

于 2011-10-12T21:37:05.980 に答える