C++ 如何初始化Guchar Gtk3

C++ 如何初始化Guchar Gtk3,c++,linux,gtk3,glib,gdkpixbuf,C++,Linux,Gtk3,Glib,Gdkpixbuf,我试图在Gtk窗口中显示图像我将图像作为std::string存储在内存中,我试图显示它,但我似乎无法将图像放入GdkPixbuf*。 这是我的函数,它获取图像数据,我知道它可以工作,因为如果我将数据写入文件,我可以打开它 string getFileInMem(string url){ cURLpp::Easy handle; std::ostream test(nullptr); std::stringbuf str; test.rdbuf(&str)

我试图在Gtk窗口中显示图像我将图像作为std::string存储在内存中,我试图显示它,但我似乎无法将图像放入
GdkPixbuf*
。 这是我的函数,它获取图像数据,我知道它可以工作,因为如果我将数据写入文件,我可以打开它

string getFileInMem(string url){
    cURLpp::Easy handle;
    std::ostream test(nullptr);
    std::stringbuf str;
    test.rdbuf(&str);
    char* error[CURL_ERROR_SIZE];
    handle.setOpt(cURLpp::Options::Url(url));
    handle.setOpt(cURLpp::options::FollowLocation(true));
    handle.setOpt(cURLpp::options::WriteStream(&test));
    handle.setOpt(cURLpp::options::ErrorBuffer(*error));
    //cout << error << endl;
    handle.perform();
    string tmp = str.str();
    return tmp;
}

只需将数据转换为
(const guchar*)
就可以了

int main(int argc, char *argv[]){

string data = getFileInMem("0.0.0.0:8000/test.txt");


GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
gdk_pixbuf_loader_write(loader,(const guchar*)data.data(),data.size(),nullptr);
GdkPixbuf* imagedata = gdk_pixbuf_loader_get_pixbuf(loader);
GtkWidget *image = gtk_image_new_from_pixbuf(imagedata);

//  creating the window with the image
GtkWidget *window;
GtkWidget *button;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_add(GTK_CONTAINER(window),image);
gtk_widget_show_all(window);
gtk_main ();
return 0;

<>我必须承认我不是GDK专家,但我已经使用C多年了,我用C++多年了,BTW.我已经用GTKMM编程(C++绑定了GTK+)多年前。因此,我觉得我能够理清什么可能会让OP感到困惑

C字符串 字符串的处理在过去是一些不同方法的主题

例如,在PASCAL中,字符串始终是256字节的数组。第一个字节是为字符串的长度保留的,即resp。包含字符的其他字节数。这是一个安全的解决方案,但也有缺点:即使最短的字符串也总是消耗256字节。更糟糕的是,超过255个字符的字符串是不可能的。在这种情况下,有一些变通方法可以创建字符串列表,但实际上这很烦人

在C中,它的解决方式不同。字符串可以具有任意长度(只要它们适合计算机内存)。长度本身不会被存储。相反,字符串的结尾用一个特殊字符
'\0'
——一个值为0的字节——来表示,它是专门为此目的保留的。缺点是:字符串的长度必须单独存储,或者必须根据第一次出现
'\0'
之前的字符数来确定。C标准库为此提供了一个就绪函数:。这样就可以根据字符串的第一个字符的地址来处理字符串。因此,C字符串由
char*
处理(如果不能修改C字符串,则由
const char*
处理)

C库提供了一些额外的函数来支持使用C字符串的工作,例如
strcpy()
将连续字节从源指针(第2个参数)复制到目标指针(第1个参数),直到出现
'\0'
字节。(它也会被复制,但函数会在之后结束。)

二进制数据 二进制数据(由具有任意值的字节组成)可以像C字符串一样处理
char
是一种整数类型,大小为1字节。因此,它也是合适的候选人。但是,二进制数据可能在任何位置包含任何可能的值0…255。因此,用
'\0'
标记结尾的原则不起作用。相反,长度必须始终单独存储

对于二进制数据的处理,
无符号字符
通常是首选。IMHO,这有两个基本原因:

  • 它帮助程序员区分C字符串和指向任意二进制数据的指针
  • 代码> char < /> >可以(由C标准以及C++标准)签署或未签名(取决于编译器供应商的决定)。如果
    char
    值的签名是一个问题,则必须使用
    signed char
    unsigned char
    。对于处理二进制数据的字节,显式处理它们通常更方便
    无符号
    标准C库提供了resp。处理二进制数据的函数,例如。请注意,
    memcpy()
    提供了第三个参数来定义从源指针复制到目标指针的字节大小

    存储 除了C字符串的优点之外,它们还带来了一个负担:程序员负责始终提供足够的存储。在C中,有多种可能性:

    • 使用带有
      char
      数组的全局变量,例如
      静态char数据[1024]
    • 使用带有
      char
      数组的局部变量(在函数中),例如
      char数据[1024]
    • 在堆上分配内存,例如
      char*data=malloc(1024)
    字符数组的大小必须在程序中定义(在编译时)。无法在程序运行时更改此设置。(例外情况是,根据C99标准,它们是可选的特征,但即使在最近的C++标准中也没有这样的东西,尽管有些C++编译器将它们作为专有扩展提供。) 如果在运行前不知道存储的大小,则动态内存的分配是唯一的解决方案(即
    size\ut n=somehowthedetermined();char*data=malloc(n);

    管理足够的存储声音实际上并不那么复杂,但要正确组织并始终正确地显示C和C++程序中的主要问题之一。(C++继承了这个问题,C++中有一个< <代码>新< /COD>运算符和<代码>删除< /COD>运算符,以允许堆上类型安全分配,但实际上没有多大帮助。因此,C++标准委员会多年来投入了大量的安全替换。

    字符串 <>在C++中,字符串可以存储为<代码> STD::String < /代码>。它让有弦的生活变得容易多了。例如,C字符串必须与 StrcMP()/Cube >或类似的内容相比较,C++ >代码> STD::String 提供了一个重载的<代码>运算符==())/Cord>,它允许直观代码,例如“代码> STD::String Text=输入());如果(文本==“退出”)退出()
    std::string
    的另一个重要优点是内部内存管理。字符串可以添加到字符串中,也可以插入字符串中,等等,
    std::string
    将关注内部存储的正确分配

    此外,
    std::string
    在内部存储其内容的大小。(作者们可能发现,将额外的字节用于另一个积分是值得的,这样它就不存在了。)
    int main(int argc, char *argv[]){
    
    string data = getFileInMem("0.0.0.0:8000/test.txt");
    
    
    GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
    gdk_pixbuf_loader_write(loader,(const guchar*)data.data(),data.size(),nullptr);
    GdkPixbuf* imagedata = gdk_pixbuf_loader_get_pixbuf(loader);
    GtkWidget *image = gtk_image_new_from_pixbuf(imagedata);
    
    //  creating the window with the image
    GtkWidget *window;
    GtkWidget *button;
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_add(GTK_CONTAINER(window),image);
    gtk_widget_show_all(window);
    gtk_main ();
    return 0;
    
    std::string data;
    // image file somehow read in
    guchar* pixdata = new guchar[data.size()+1];// creating a guchar* with space for image data
    strcpy((char*)pixdata,data.c_str());// copying data from string to the guchar*
    
    std::string data;
    // image file somehow read in
    GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
    gdk_pixbuf_loader_write(loader, (const guchar*)data.data(), data.size(), nullptr);
    
    gdk_pixbuf_loader_write(loader, (const guchar*)data.c_str(), data.size(), nullptr);
    
    typedef unsigned char   guchar;
    
    string data = getFileInMem("0.0.0.0:8000/test.txt");
    guchar* pixdata = (const guchar*)data.data();
    
    GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
    gdk_pixbuf_loader_write(loader,pixdata,sizeof(pixdata),nullptr);
    
    string data = getFileInMem("0.0.0.0:8000/test.txt");
    const guchar* pixdata = (const guchar*)data.data();
    
    GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
    gdk_pixbuf_loader_write(loader, pixdata, data.size(), nullptr);
    
    string data = getFileInMem("0.0.0.0:8000/test.txt");
    const guchar* pixdata = (const guchar*)data.data();
    gsize pixdatasize = (gsize)data.size();
    GdkPixbufLoader* loader = gdk_pixbuf_loader_new();
    gdk_pixbuf_loader_write(loader, pixdata, pixdatasize, nullptr);