如何修复传递给pango_layout_set_text()的无效UTF-8字符串

时间:2012-10-29 04:20:53

标签: c gtk gtk3 pango

我从使用gtk +的应用程序收到以下警告:

(foo:11333): Pango-WARNING **: Invalid UTF-8 string passed to pango_layout_set_text()

发出警告的功能如下:

static void show_error(GtkWindow *parent, const gchar *fmt, ...)
{
  GtkWidget *dialog;
  va_list args;

  va_start(args,fmt);
  dialog = gtk_message_dialog_new(parent,
                  GTK_DIALOG_DESTROY_WITH_PARENT,
                  GTK_MESSAGE_ERROR,
                  GTK_BUTTONS_OK,
                  fmt,
                  args);

  (void)gtk_dialog_run(GTK_DIALOG(dialog));

  gtk_widget_destroy(dialog);
  va_end(args);
}

我打电话给ui_show_error(window, "error canno't read file %s", filename);

其中filename为null-terminatted-string,适用于str*()*printf()函数系列。

如何解决这个问题?

3 个答案:

答案 0 :(得分:4)

以这种方式链接va_list参数是不可能的。见this faq entry。正在发生的事情是gtk_message_dialog_new将va_list参数(具有一些编译器定义的格式)解释为指向字符串的指针,因此您将获得垃圾。由于没有带有va_list的消息对话框函数,因此您唯一的选择是使用vsprintf或其中一个类似的glib函数构建一个字符串,并将其作为一个参数传递给gtk_message_dialog_new,格式为“%s”。

要在未知格式字符串的情况下构建字符串,通常该技术使用“n”变体之一,如vsnprintf和较大的缓冲区,如果发生截断,则增加缓冲区大小和做完了。但是,glib有g_vasprintf(),它为您分配缓冲区。它还有g_printf_string_upper_bound(),可用于根据格式字符串调整缓冲区大小。

答案 1 :(得分:1)

我在Linux From Scratch(LFS)版本中遇到了这个问题。 问题是影响java swing接口文本输入,gdk接口文本输入,有时默默忽略输入,如文本字段被禁用。 原因是没有任何UTF8语言环境。 就我而言:

$ locale -a
C
POSIX
pt_BR
pt_BR.iso88591

所以,为了解决我确实定义了一个新的语言环境类型utf8,如:

localedef -i pt_BR -f UTF-8 pt_BR.UTF-8
在此之后,所有这些都变得有用,没有更多的警告。至少在我的情况下。

答案 2 :(得分:0)

OP没有显示实际字符串,ui_show_error函数在哪里? 什么Gtk +版本?默认情况下,gtk_message_dialog_new“use-markup”属性为 FALSE,帖子上还有什么东西丢失了吗?

你可以这样做:

msg = g_vasprintf(fmt, args);

if (strstr(msg, "</"))
  msg_has_markup = TRUE;

dialog = g_object_new (GTK_TYPE_MESSAGE_DIALOG,
                       "message-type",         GTK_MESSAGE_ERROR,
                       "text",                 msg,
                       "use-markup",           msg_has_markup,
                       "buttons",              GTK_BUTTONS_OK,
                        NULL);
g_free (msg);

注意如果文件名字符串仍然会收到相同的错误消息 包含在“&lt;&gt;”中,即</home/somebody会导致令人讨厌的pango消息。 要么不使用“&lt;&gt;”或者不要使用pango。