1. 程式人生 > >GTK+亂碼錯誤,提示:Invalid UTF-8 string passed to pango_layout_set_text()

GTK+亂碼錯誤,提示:Invalid UTF-8 string passed to pango_layout_set_text()

今天照著"Foundations of GTK+ Development"的練習題做了一個exercise2-1,出現如題的錯誤。我上網搜尋了下,

發現都是說環境變數LANG設定的問題,但是我啟用中文或者在其它程式裡面都沒出現這個錯誤,於是嚴重懷疑我的程式碼

出現錯誤了。先還是貼上程式碼,讓自己出出醜吧,這個錯誤真該好好記住!

我當時很奇怪(見程式碼中我的註釋),後來在gtk mailing list的各位朋友幫助下才搞明白了:widgets中的標題等屬性是由

其類進行分配記憶體的,如果其中某個部分不使用了,則會自動釋放該部分的記憶體。所以當我呼叫gtk_window_set_title後,

window的title改變了(複製了textLabel指向的內容),原來的title佔用的記憶體被釋放,當我繼續呼叫下面一句gtk_label_

set_text時候,textWindow所指向的已經為空(不一定為空,只是系統給他亂分配了個),亂碼當然也就難免啦。哎,悲哀。

只能把那個回撥函式修改如下:

可見,GTK 的widgets裡面的屬性都是由widgets自己掌控的,重新設定的內容也被複制到其內部了。這一點由g_free可以

看出,如果僅僅是用一個指標指向新的內容,那麼這裡其標題又會不見了吧。

我想,我需要記住的是:GTK中widgets裡面的屬性都是由widgets自己掌控,不需要的內容都會被widget釋放。

如果覺得我解釋的不夠清楚,請看這位GTK mailing list上的Kristian Rietveld的解釋吧:

You have to note that textLabel and
textWindow both point to a string that is internal to the
GtkLabel/GtkWindow widgets.  This is why the string has to the const,
you are not allowed to modify that internal string directly.  The
point is that when you set another title or text, this internal string
will be replaced with the new string.  So as soon as you call
gtk_window_set_title(), the internal title string will be replaced and
after this call your textWindow pointer is no longer valid (because it
points to this internal string that has been replaced).  But you still
have to use it for the call to gtk_label_set_text().  Swapping the
calls will not help, because gtk_label_set_text() does the same and
textLabel will become invalid.