2

カスタム ストリーミング (複数のバイナリ ファイル) でマルチパート MIME メッセージを送信しようとしています。この目的のために、CURLOPT_READFUNCTIONコールバックに によって設定されたポインタを使用させることができませんCURLFORM_STREAM

私が知る限り、データのストリーミングを開始するとCURLFORM_STREAMドキュメントはポインターを自動的に呼び出します。CURLOPT_READFUNCTIONこれは私には起こっていません。

これが私の現在のコード サンプルです (さまざまな構成を試しましたが成功しませんでした)。エラー時に例外をスローするマクロですCURLCODECHECK。私自身の構造体のベクトルです。CURLFORMCHECKstreamsStreamData

        CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_HTTPPOST, 1L));
        CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_READFUNCTION, ::StreamReadFunction));

        for (auto iter = streams.begin(); iter != streams.end(); ++iter)
        {
            std::string const & name = iter->first;
            auto streamData = iter->second;

            CURLFORMCHECK(curl_formadd(&m_Post, &last,
                CURLFORM_COPYNAME, name.c_str(),
                CURLFORM_FILENAME, streamData->fileName.c_str(),
                CURLFORM_CONTENTTYPE, streamData->mimeType.c_str(),
                CURLFORM_STREAM, (void *) streamData.get(),
                CURLFORM_CONTENTSLENGTH, streamData->size,
                CURLFORM_END));
        }

::StreamReadFunctionは呼び出されますがcurl_easy_setopt()CURLOPT_READDATAset で呼び出さない限り、4 番目の (void * userdata) 引数に null ポインターが渡されます。

4

1 に答える 1

1

要するに、の代わりにCURLOPT_HTTPPOSTはなりませんCURLOPT_POST。両方を指定する必要があり、最初CURLOPT_POSTに設定する必要があります。

curl_formadd()呼び出しを関数の先頭に移動し、次のように続けました。

CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_POST, 1L));
CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_POSTFIELDSIZE, fieldSize));
CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_READFUNCTION, ::StreamReadFunction));
CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_HTTPPOST, m_Post));
CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_VERBOSE, 1L));
CURLCODECHECK(curl_easy_setopt(m_Curl, CURLOPT_HEADER, 1L));

::StreamReadFunctionこれにより、ストリーム ポインターを使用して適切に呼び出されました。

ストリーム コールバックが適切なポインターを使用するには、事前CURLOPT_POSTに設定する必要があることに注意してください(後で配置すると、null ポインターが渡されます)。 CURLOPT_HTTPPOSTCURLOPT_POST

于 2013-02-11T19:25:37.563 に答える