3

私はCでプログラムされたLinuxアプリを開発しています。このアプリは、gdk pixbufイメージを処理し、ftp(libcurl)経由でリモートサーバーに送信する必要があります。画像はgdk_pixbuf_save_to_bufferでgcharバッファに保存されます。

問題は、このバッファ内のデータをlibcurl読み取りコールバック関数と組み合わせて使用​​して画像をリモートサーバーに適切に送信する方法がわからないことです。これまでの私の試みはすべて、結果のファイルにランダムなバイトを生成しました。

次のようなlibcurl読み取りコールバック関数の例があります。

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *stream)
{
    size_t retcode = fread(ptr, size, nmemb, stream);
    return retcode;
} 

ファイルストリームの代わりにgcharバッファを入力として取得し、そこからsize * nmembバイトを読み取り、*ptrに格納する独自のコールバック関数を実行する必要があります。

これは私の前の質問に関連しています。

4

1 に答える 1

4

これread_callback()は、サーバーにアップロードされるデータを取得する必要があるときにCURLが呼び出す関数です。に似たものを想像してみてread_callback()ください。呼び出されると、必要なブードゥーマンボジャンボを実行しますが、最終的にアップロード可能なデータは、curlの内部バッファーであるバッファーに格納する必要があります。インメモリバッファはの本体として問題なく動作するため、実際のバッファはまったく必要ありません。fread()*ptrmemcpy()read_callback()fread()

size * nmemb単一のデータチャンク用にどのくらいの大きさのバッファーcurlが予約されているかを示します。最後void*は、CURLOPT_READDATAオプションによって設定されたポインターです。これは、必要に応じて実行できる一種のポインターであるため、アップロードするデータといくつかの追加情報を含む構造体を指すことができます。例:現在の進捗状況。

これをサンプルとして使用できます。

#include <gdk-pixbuf/gdk-pixbuf.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <string.h>

struct transfer
{
    gchar *buf;
    gsize total;
    size_t uploaded;
};

static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *data)
{
    struct transfer * tr = data;
    size_t left = tr->total - tr->uploaded;
    size_t max_chunk = size * nmemb;
    size_t retcode = left < max_chunk ? left : max_chunk;

    memcpy(ptr, tr->buf + tr->uploaded, retcode); // <-- voodoo-mumbo-jumbo :-)

    tr->uploaded += retcode;  // <-- save progress
    return retcode;
} 

int main()
{
    GdkPixbuf * gbuffer = NULL;
    GError * error = NULL;
    gchar * buffer;
    gsize size;
    g_type_init();
    gbuffer = gdk_pixbuf_new_from_file("g.png", &error);
    gdk_pixbuf_save_to_buffer(gbuffer, &buffer, &size, "jpeg", &error, NULL);

    struct transfer tr = {buffer, size, 0};

    CURL *easyhandle = curl_easy_init();
    curl_easy_setopt(easyhandle, CURLOPT_READFUNCTION, read_callback); 
    curl_easy_setopt(easyhandle, CURLOPT_READDATA, &tr); // <-- this will be *data in read_callback()
    curl_easy_setopt(easyhandle, CURLOPT_UPLOAD, 1L); 
    curl_easy_setopt(easyhandle, CURLOPT_URL, "http://example.com/upload.php");
    CURLcode rc = curl_easy_perform(easyhandle);
}
于 2012-02-26T22:24:08.467 に答える