2012-02-26 49 views
2

我正在開發一個用C編程的linux應用程序,它處理gdk pixbuf圖像,然後通過ftp(libcurl)將它們發送到遠程服務器。圖像保存到gdk_pixbuf_save_to_buffer的gchar緩衝區中。從gchar緩衝區發送圖像到ftp服務器(libcurl)

問題是我不知道如何將此緩衝區中的數據與libcurl read callback function一起使用,以將映像正確地發送到遠程服務器。到目前爲止,我所有的嘗試都將隨機字節輸入到生成的文件中。

還有就是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緩衝區作爲輸入,而不是文件流和讀取尺寸*從它nmemb字節並將其存儲到* ptr。

這與我的previous question有關。

回答

2

read_callback()是CURL在需要獲取將要上傳到服務器的數據時調用的一個函數。想象一下,read_callback()類似的東西fread()。當被調用時,它會執行所需的任何Voodoo-mumbo-jumbo,但最終上載的數據必須存儲在緩存中,該緩存是curl的內部緩存。對於你的內存緩衝區memcpy()將會做得很好,因爲它的主體是read_callback(),所以你完全不需要真正的fread()

size * nmemb告訴您爲單個數據塊保留了多大的緩衝區捲曲。最後一個void*是一個由CURLOPT_READDATA選項設置的指針 - 它是一種你所需要的,隨它一樣的指針,所以它可以指向一個包含你正在上傳的數據的結構,以及一些額外的info例如現在的進展。

你可以使用這個作爲樣本:

#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); 
} 
+0

大,非常感謝! – drwn 2012-02-26 23:52:44

+0

我們可以控制libcurl傳遞的「size_t size,size_t nmemb」params嗎?這裏是場景,我想上傳2 GB的文件,但不想將內存中的2GB讀取到緩衝區,或讓curl決定從傳遞的文件指針發送多少。我想在發送時控制金額數據從文件讀取,有可能嗎? – heisenberg 2017-08-26 10:32:16