我如何初始化 Guchar Gtk3
how do I initialize a Guchar Gtk3
我正在尝试在 Gtk 中显示图像 window 我将图像作为 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;
}
这是调用 get FileInMem()
的主循环。我已经将数据输入 guchar* 并打印出来,但是一旦我这样做了,我就无法编写任何其他指令,或者出现核心转储错误 任何在 [=21= 中显示图像的方法] 不写入磁盘会很棒
int main(int argc, char *argv[]){
string data1 = getFileInMem("0.0.0.0:8000/test.txt");
ofstream f("test.jpg");// image file
f << data;// writing image data the file
f.close();// closing the file
GdkPixbufLoader* loader = gdk_pixbuf_loader_new(); // creating a pixbuf loader
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*
gdk_pixbuf_loader_write(loader,pixdata,sizeof(pixdata),nullptr);// trying to write the data to the loader
GdkPixbuf* imagedata = gdk_pixbuf_loader_get_pixbuf(loader);// creating the pixbuf*
GtkWidget *image = gtk_image_new_from_pixbuf(imagedata);
delete pixdata;// deleting pixdata once done with it
// 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;
}
只需将数据转换为 (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++ 也多年,顺便说一句。几年前,我使用 gtkmm(GTK+ 的 C++ 绑定)进行编程。因此,我觉得能够理清可能让 OP 感到困惑的内容。
C 字符串
字符串的处理在过去是一些不同方法的主题。
例如在 PASCAL 中,字符串始终是 256 字节的数组。第一个字节保留用于字符串的长度,resp。包含字符的其他字节数。这是一个安全的解决方案,但它也有缺点:即使是最短的字符串也总是占用 256 个字节。更糟糕的是,不可能有超过 255 个字符的字符串。在这种情况下,可以使用变通方法来创建字符串列表,但这实际上很烦人。
在 C 中,它的解决方式不同。字符串可以具有任意长度(只要它们适合计算机的内存)。长度本身不存储。相反,字符串的末尾由一个特殊字符 '[=21=]'
标记——一个值为 0 的字节——专门为此目的保留。缺点是:字符串的长度必须单独存储,或者必须计算直到第一个出现'[=21=]'
的字符来确定。 C标准库为此提供了一个现成的函数:strlen()。这使得可以通过第一个字符的地址来处理字符串。因此,C 字符串由 char*
处理(如果不能修改 C 字符串,则由 const char*
处理)。
C 库提供了一些额外的函数来支持使用 C 字符串,例如strcpy()。 strcpy()
将连续字节从源指针(第二个参数)复制到目标指针(第一个参数),直到出现 '[=21=]'
字节。 (也被复制了,但是函数后来结束了。)
二进制数据
二进制数据(由具有任意值的字节组成)可以像 C 字符串一样处理。 char
是一个整数类型,大小为 1 个字节。因此,它也是合适的人选。但是,二进制数据可能在任何位置包含任何可能的值 0 … 255。所以,用 '[=21=]'
来表示结尾的原则是行不通的。相反,长度必须始终单独存储。
对于二进制数据的处理,unsigned char
通常是首选。恕我直言,这有两个基本原因:
- 它可以帮助程序员区分 C 字符串和指向任意二进制数据的指针。
char
可以(根据 C 标准和 C++ 标准)有符号或无符号(取决于相应的编译器供应商的决定)。如果 char
值的符号性是一个问题,则必须使用 signed char
或 unsigned char
来代替。对于处理二进制数据的字节,显式处理它们通常更方便 unsigned
.
标准 C 库提供 resp。还有处理二进制数据的函数,例如memcpy()。请注意,memcpy()
提供了第三个参数来定义要从源指针复制到目标指针的字节大小。
存储空间
除了 C 字符串的优点之外,它们也有一个负担:程序员有责任始终提供足够的存储空间。在C中,有多种可能:
- 使用带有
char
数组的全局变量,例如static char data[1024];
- 使用带有
char
数组的局部变量(在函数中),例如char data[1024];
- 在堆上分配内存,例如
char *data = malloc(1024);
.
字符数组的大小必须在程序中定义(在编译时)。无法在程序运行 运行 时更改此设置。 (例外是 Variable Length Arrays。根据 C99 标准,它们是可选功能,但即使在最近的 C++ 标准中也没有这样的东西,尽管一些 C++ 编译器将它们作为专有扩展提供。)
如果在 运行 时间之前不知道存储大小,则动态内存分配是唯一的解决方案(即 size_t n = somehowDetermined(); char *data = malloc(n);
)。
管理足够的存储空间听起来实际上并没有那么复杂,但正确地组织它并始终正确地显示为多年来 C 和 C++ 程序中的基本问题之一。 (C++ 从 C 继承了这个问题。添加了 new
运算符和 delete
运算符以允许在堆上进行类型安全分配,但实际上这并没有多大帮助。)因此,C++ 标准委员会有多年来在更安全的替代品上投入了大量资金。
std::string
在 C++ 中,字符串可能存储为 std::string
。它使使用字符串的生活变得更加轻松。例如。虽然 C 字符串必须与 strcmp()
或类似的东西进行比较,但 C++ std::string
提供了一个重载的 operator==()
允许直观的代码,例如std::string text = input(); if (text == "exit") exit();
。
std::string
的另一个重要优势是内部内存管理。可以将字符串添加到字符串、插入字符串等,std::string
会自行关心内部存储的正确分配。
此外,std::string
在内部存储其内容的大小。 (作者可能发现为另一个整数花费额外的字节是值得的,这样就不必计算任何字符串长度检索的字符数。)这使得 std::string
也足以容纳二进制数据。
为了与 C API 兼容,std::string
提供了一个“后门”std::string::c_str(). It provides the raw contents of the std::string
as C string. It grants that the returned C string has a '[=21=]'
byte after the last character i.e. std::string::c_str()[std::string::size()]
must return '[=21=]'
. There is also a std::string::data() 函数来访问 std::string
的原始数据。在 C++11 之前,只有 std::string::c_str()
必须授予终止符 0 而不是 std::string::data()
。在 C++11 中,这发生了变化。现在,std::string::data()
和 std::string::c_str()
的 return 值应该没有任何区别——两者都只是 return 指向内部存储的原始数据的指针。因此,无论内容如何,std::string
实际上必须始终在末尾放置一个 '[=21=]'
字符。这可能看起来是一种浪费,但实际上,我们谈论的是一个额外的字节,这是一个很小的代价,但对代码的健壮性有很大的好处。
OP 代码
考虑到OP要从内存中加载图像文件(通常由任意字节组成),下面的代码是错误的:
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*
对于任意二进制数据,strcpy()
是错误的。它复制直到找到第一个 0 字节。图像数据中的任何地方都可能有 0 个字节(例如,如果它包含黑色像素)。因此,很有可能 strcpy()
复制的字节太少。在这种情况下,memcpy()
将是更好的选择。
其实两者都没有必要。
std::string data;
已经包含了必须输入 gdk_pixbuf_loader_write()
的所有内容,指向原始数据的指针和大小。
因此,我建议完全删除 new[]
和 delete
内容并用以下内容替换它:
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);
正如我已经解释过的,自 C++11 以来这没有任何区别。我使用 data.data()
只是因为它看起来更好(考虑到 std::string
的内容是二进制数据而不是 C 字符串这一事实)。
关于转换为 const guchar*
的注意事项:
std::string
在内部存储一个动态分配的 char
数组。因此,std::string::data()
returns const char*
(或char*
)。
gdk_pixbuf_loader_write() 需要一个 const guchar*
作为第二个参数。
guchar 就是一个
typedef unsigned char guchar;
因此,const char*
被转换为 const unsigned char*
。指针类型转换应该小心进行。 (一般来说,它们是某些可能被设计破坏并承担 Undefined Behavior – the plague of every C and C++ programmer.) In this case, the conversion is safe, and it's legal according to the C++ standard. I found another answer which explains this in detail: SO: Can I turn unsigned char into char and vice versa?.
危险的最后手段。
OP 尝试修复代码
经过我的一些提示,OP 提出了以下修复:
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);
不幸的是,此解决方案引入了一个新错误:sizeof(pixdata)
。
虽然 data.size()
return 是 data
中字符串长度的大小,但 sizeof(pixdata)
运算符在这里是错误的选择。
sizeof 是一个运算符,它总是在编译时解析 - return 在它的右侧计算类型的大小。它可以用类型或表达式调用:
std::cout << sizeof (char) << std::endl;
char c;
std::cout << sizeof c << std::endl;
将输出:
1
1
因此,表达式甚至不需要在 运行 时有效存储,因为 sizeof
总是在编译时解析并基于结果表达式的类型:
char *c = nullptr;
std::cout << sizeof *c << std::endl;
将输出:
1
这可能令人惊讶,因为 *c
看起来像访问空指针的内容(通常是未定义的行为)。在这种情况下,实际上不是。由于 sizeof
运算符在编译时评估类型,因此生成的代码仅包含此评估的结果。因此,在运行时没有发生*c
,并且代码中没有出现未定义的行为。
但是,sizeof pixdata
不是 return data
的大小,而是 guchar*
指针的大小。如果 OP 在 32 位平台上编译,它可能是 4,在 64 位平台上可能是 8——但对于特定平台它总是相同的值。
所以,要解决这个问题必须是:
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);
答案很长。这可能说明即使是某些 C++ 代码行也需要大量的背景知识才能正确编写它们。因此,入门级程序员经常被暗示获得 good C++ book 是有道理的。我不会坚持认为不可能以另一种方式学习 C++。但是,恕我直言,一本好的 C++ 书籍值得考虑。 C++中有很多陷阱,大部分是从C继承而来的,也有一些是C++本身专门引入的。
我正在尝试在 Gtk 中显示图像 window 我将图像作为 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;
}
这是调用 get FileInMem()
的主循环。我已经将数据输入 guchar* 并打印出来,但是一旦我这样做了,我就无法编写任何其他指令,或者出现核心转储错误 任何在 [=21= 中显示图像的方法] 不写入磁盘会很棒
int main(int argc, char *argv[]){
string data1 = getFileInMem("0.0.0.0:8000/test.txt");
ofstream f("test.jpg");// image file
f << data;// writing image data the file
f.close();// closing the file
GdkPixbufLoader* loader = gdk_pixbuf_loader_new(); // creating a pixbuf loader
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*
gdk_pixbuf_loader_write(loader,pixdata,sizeof(pixdata),nullptr);// trying to write the data to the loader
GdkPixbuf* imagedata = gdk_pixbuf_loader_get_pixbuf(loader);// creating the pixbuf*
GtkWidget *image = gtk_image_new_from_pixbuf(imagedata);
delete pixdata;// deleting pixdata once done with it
// 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;
}
只需将数据转换为 (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++ 也多年,顺便说一句。几年前,我使用 gtkmm(GTK+ 的 C++ 绑定)进行编程。因此,我觉得能够理清可能让 OP 感到困惑的内容。
C 字符串
字符串的处理在过去是一些不同方法的主题。
例如在 PASCAL 中,字符串始终是 256 字节的数组。第一个字节保留用于字符串的长度,resp。包含字符的其他字节数。这是一个安全的解决方案,但它也有缺点:即使是最短的字符串也总是占用 256 个字节。更糟糕的是,不可能有超过 255 个字符的字符串。在这种情况下,可以使用变通方法来创建字符串列表,但这实际上很烦人。
在 C 中,它的解决方式不同。字符串可以具有任意长度(只要它们适合计算机的内存)。长度本身不存储。相反,字符串的末尾由一个特殊字符 '[=21=]'
标记——一个值为 0 的字节——专门为此目的保留。缺点是:字符串的长度必须单独存储,或者必须计算直到第一个出现'[=21=]'
的字符来确定。 C标准库为此提供了一个现成的函数:strlen()。这使得可以通过第一个字符的地址来处理字符串。因此,C 字符串由 char*
处理(如果不能修改 C 字符串,则由 const char*
处理)。
C 库提供了一些额外的函数来支持使用 C 字符串,例如strcpy()。 strcpy()
将连续字节从源指针(第二个参数)复制到目标指针(第一个参数),直到出现 '[=21=]'
字节。 (也被复制了,但是函数后来结束了。)
二进制数据
二进制数据(由具有任意值的字节组成)可以像 C 字符串一样处理。 char
是一个整数类型,大小为 1 个字节。因此,它也是合适的人选。但是,二进制数据可能在任何位置包含任何可能的值 0 … 255。所以,用 '[=21=]'
来表示结尾的原则是行不通的。相反,长度必须始终单独存储。
对于二进制数据的处理,unsigned char
通常是首选。恕我直言,这有两个基本原因:
- 它可以帮助程序员区分 C 字符串和指向任意二进制数据的指针。
char
可以(根据 C 标准和 C++ 标准)有符号或无符号(取决于相应的编译器供应商的决定)。如果char
值的符号性是一个问题,则必须使用signed char
或unsigned char
来代替。对于处理二进制数据的字节,显式处理它们通常更方便unsigned
.
标准 C 库提供 resp。还有处理二进制数据的函数,例如memcpy()。请注意,memcpy()
提供了第三个参数来定义要从源指针复制到目标指针的字节大小。
存储空间
除了 C 字符串的优点之外,它们也有一个负担:程序员有责任始终提供足够的存储空间。在C中,有多种可能:
- 使用带有
char
数组的全局变量,例如static char data[1024];
- 使用带有
char
数组的局部变量(在函数中),例如char data[1024];
- 在堆上分配内存,例如
char *data = malloc(1024);
.
字符数组的大小必须在程序中定义(在编译时)。无法在程序运行 运行 时更改此设置。 (例外是 Variable Length Arrays。根据 C99 标准,它们是可选功能,但即使在最近的 C++ 标准中也没有这样的东西,尽管一些 C++ 编译器将它们作为专有扩展提供。)
如果在 运行 时间之前不知道存储大小,则动态内存分配是唯一的解决方案(即 size_t n = somehowDetermined(); char *data = malloc(n);
)。
管理足够的存储空间听起来实际上并没有那么复杂,但正确地组织它并始终正确地显示为多年来 C 和 C++ 程序中的基本问题之一。 (C++ 从 C 继承了这个问题。添加了 new
运算符和 delete
运算符以允许在堆上进行类型安全分配,但实际上这并没有多大帮助。)因此,C++ 标准委员会有多年来在更安全的替代品上投入了大量资金。
std::string
在 C++ 中,字符串可能存储为 std::string
。它使使用字符串的生活变得更加轻松。例如。虽然 C 字符串必须与 strcmp()
或类似的东西进行比较,但 C++ std::string
提供了一个重载的 operator==()
允许直观的代码,例如std::string text = input(); if (text == "exit") exit();
。
std::string
的另一个重要优势是内部内存管理。可以将字符串添加到字符串、插入字符串等,std::string
会自行关心内部存储的正确分配。
此外,std::string
在内部存储其内容的大小。 (作者可能发现为另一个整数花费额外的字节是值得的,这样就不必计算任何字符串长度检索的字符数。)这使得 std::string
也足以容纳二进制数据。
为了与 C API 兼容,std::string
提供了一个“后门”std::string::c_str(). It provides the raw contents of the std::string
as C string. It grants that the returned C string has a '[=21=]'
byte after the last character i.e. std::string::c_str()[std::string::size()]
must return '[=21=]'
. There is also a std::string::data() 函数来访问 std::string
的原始数据。在 C++11 之前,只有 std::string::c_str()
必须授予终止符 0 而不是 std::string::data()
。在 C++11 中,这发生了变化。现在,std::string::data()
和 std::string::c_str()
的 return 值应该没有任何区别——两者都只是 return 指向内部存储的原始数据的指针。因此,无论内容如何,std::string
实际上必须始终在末尾放置一个 '[=21=]'
字符。这可能看起来是一种浪费,但实际上,我们谈论的是一个额外的字节,这是一个很小的代价,但对代码的健壮性有很大的好处。
OP 代码
考虑到OP要从内存中加载图像文件(通常由任意字节组成),下面的代码是错误的:
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*
对于任意二进制数据,strcpy()
是错误的。它复制直到找到第一个 0 字节。图像数据中的任何地方都可能有 0 个字节(例如,如果它包含黑色像素)。因此,很有可能 strcpy()
复制的字节太少。在这种情况下,memcpy()
将是更好的选择。
其实两者都没有必要。
std::string data;
已经包含了必须输入 gdk_pixbuf_loader_write()
的所有内容,指向原始数据的指针和大小。
因此,我建议完全删除 new[]
和 delete
内容并用以下内容替换它:
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);
正如我已经解释过的,自 C++11 以来这没有任何区别。我使用 data.data()
只是因为它看起来更好(考虑到 std::string
的内容是二进制数据而不是 C 字符串这一事实)。
关于转换为 const guchar*
的注意事项:
std::string
在内部存储一个动态分配的 char
数组。因此,std::string::data()
returns const char*
(或char*
)。
gdk_pixbuf_loader_write() 需要一个 const guchar*
作为第二个参数。
guchar 就是一个
typedef unsigned char guchar;
因此,const char*
被转换为 const unsigned char*
。指针类型转换应该小心进行。 (一般来说,它们是某些可能被设计破坏并承担 Undefined Behavior – the plague of every C and C++ programmer.) In this case, the conversion is safe, and it's legal according to the C++ standard. I found another answer which explains this in detail: SO: Can I turn unsigned char into char and vice versa?.
OP 尝试修复代码
经过我的一些提示,OP 提出了以下修复:
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);
不幸的是,此解决方案引入了一个新错误:sizeof(pixdata)
。
虽然 data.size()
return 是 data
中字符串长度的大小,但 sizeof(pixdata)
运算符在这里是错误的选择。
sizeof 是一个运算符,它总是在编译时解析 - return 在它的右侧计算类型的大小。它可以用类型或表达式调用:
std::cout << sizeof (char) << std::endl;
char c;
std::cout << sizeof c << std::endl;
将输出:
1
1
因此,表达式甚至不需要在 运行 时有效存储,因为 sizeof
总是在编译时解析并基于结果表达式的类型:
char *c = nullptr;
std::cout << sizeof *c << std::endl;
将输出:
1
这可能令人惊讶,因为 *c
看起来像访问空指针的内容(通常是未定义的行为)。在这种情况下,实际上不是。由于 sizeof
运算符在编译时评估类型,因此生成的代码仅包含此评估的结果。因此,在运行时没有发生*c
,并且代码中没有出现未定义的行为。
但是,sizeof pixdata
不是 return data
的大小,而是 guchar*
指针的大小。如果 OP 在 32 位平台上编译,它可能是 4,在 64 位平台上可能是 8——但对于特定平台它总是相同的值。
所以,要解决这个问题必须是:
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);
答案很长。这可能说明即使是某些 C++ 代码行也需要大量的背景知识才能正确编写它们。因此,入门级程序员经常被暗示获得 good C++ book 是有道理的。我不会坚持认为不可能以另一种方式学习 C++。但是,恕我直言,一本好的 C++ 书籍值得考虑。 C++中有很多陷阱,大部分是从C继承而来的,也有一些是C++本身专门引入的。