1

自分の gtk プログラムを古い MinGW から最新のものに移動したかったのです。過去 2 週間で多くの質問に出会いましたが、方法が見つかりませんでした。私が投稿した他の2つの質問を参照してください。

mingw は gtk プログラムコンパイルに影響を与え、mingw で gtk をコンパイルしますが失敗しました。

最後に、自分でコンパイルgtk+2.24.10しましたMinGW。環境の詳細は次のとおりです。

            GTK version                            gcc version
old mingw   2.10.11 -- from third party            3.4.5
new mingw   2.24.10 -- compiled by myself          4.7.2 or 4.6.2 -- I tried both

古い環境のプログラムでは、すべてが正常に動作します。

新しい環境のプログラムでは、上記の「mingw は gtk プログラムのコンパイルに影響を与えるか」という問題はなくなりました。しかし、どこから来たのか手がかりが見つからない新しい問題があります。

プログラムの起動時に GUI ウィンドウを移動すると、クラッシュしました。gdb を使用してデバッグしましたが、クラッシュするとシステムがフリーズします。唯一の方法は、「c​​trl + alt + del」を使用してタスク マネージャーを起動し、プログラムを停止することです。次にGDBで、whereまたはbt full有用な情報を表示しませんでした。GUI ウィンドウを移動しなければ、ウィンドウ内のすべての機能が正常に動作します。もう1つ、私のプログラムはサードパーティ製のopensslとを使用しています。pdflibプログラムはライブラリにリンクしますが、GUI ウィンドウが起動されたばかりのときは使用されません。

  • 自分のコードにバグはありますか? 古いMinGW環境でうまく動くので、そうは思いません。一部の警告g_thread_create, g_thread_init is deprecatedは gtk+2.24.10 パッケージにありますが、gtk+2.10.11 パッケージには表示されません。

  • MinGW で自分でコンパイルした gtk、glib、cario、atk などを含む gtk システムに問題はありますか? わかりません。しかしgtk_demo、gtk パッケージに含まれているものはうまく動作し、プログラムのウィンドウをどこにでも移動できます。

  • gccのバージョンと関係ありますか? わかりません。私がググったところ、gcc 4.7.x でコンパイルされた彼の gtk プログラムは安定しておらず、多くの突然のクラッシュの影響を受けていると不満を漏らしている人を見つけました。gcc 4.6.2 は誰かによって絶対に提案されています。しかし、私の場合、gcc 4.6.2 でコンパイルしてもクラッシュしました。

  • ABIの問題により、サードパーティからのopensslとpdflibに関連していますか? わかりません。

M コードは Linux 環境 (gtk+2.24.6) でコンパイルされます。それはうまくいきます。


更新 1 :

私はいくつかの手がかりを見つけました。問題はからthreadです。しかし、古い MinGW では機能するのに、新しい MinGW では失敗する理由はまだわかりませんでした。次に簡単な例を示します。

私が言ったように、古い MinGW でコンパイルすると、うまくいきました。データ、実際にはカウンターがウィジェットで更新されます。そして、私は窓を動かすことができます。

新しい MinGW でコンパイルすると、うまくいきました。データ、実際にはカウンターがウィジェットで更新されます。しかし、ウィンドウを移動すると、クラッシュしました。スレッドに関連することをコメントすると、ウィンドウを移動できますが、ウィンドウ内のデータは更新されません。

#include <gtk/gtk.h>

static int counter = 0;
static PangoLayout* layout;
static GdkGC* gc1;
static GdkGC* gc2;
//**/static GMutex* mu;

static gboolean on_expose_event(GtkWidget* widget, GdkEventExpose* event)
{
    gchar the_string[20];

    //**/g_mutex_lock(mu);
    gdk_draw_rectangle(GDK_DRAWABLE(widget->window), gc1, TRUE, 0, 0, widget->allocation.width, widget->allocation.height);
    snprintf(the_string, 20, "%d", counter);
    pango_layout_set_text(layout, the_string, -1);
    gdk_draw_layout(GDK_DRAWABLE(widget->window), gc2, 180, 120, layout);
    //**/g_mutex_unlock(mu);

    g_print (".");
    return FALSE;
}

gpointer func(gpointer data)
{
    //**/g_usleep(10000);
    GdkWindow* window = GDK_WINDOW(data);
    while(TRUE)
    {
  gdk_threads_enter();
        gdk_window_invalidate_rect(window, NULL, FALSE);
gdk_threads_leave();
        //**/gdk_window_process_updates(window, FALSE);
        if(counter % 100 == 0) g_print("X");
        g_usleep(10);
        ++counter;
    }
    return FALSE;
}

int main(int argc, char** argv)
{
    GtkWidget* window;
    GtkWidget* drawer;
    GdkColormap* colormap;
    GdkColor color;

    g_thread_init(NULL);
    gdk_threads_init();
    gtk_init(&argc, &argv);

    //:Create widgets and 
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    drawer = gtk_drawing_area_new();
    gtk_widget_set_size_request(drawer, 400, 300);
    gtk_container_add(GTK_CONTAINER(window), drawer);
    //.

    gtk_widget_show_all(window);

    //:Initializing Graphic Contexts
    colormap = gtk_widget_get_colormap(GTK_WIDGET(drawer));
    layout = gtk_widget_create_pango_layout(GTK_WIDGET(drawer), NULL);
    gc1 = gdk_gc_new(GDK_DRAWABLE(GTK_WIDGET(drawer)->window));
    gc2 = gdk_gc_new(GDK_DRAWABLE(GTK_WIDGET(drawer)->window));
    gdk_color_parse("#000", &color);
    gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
    gdk_gc_set_background(gc1, &color);
    gdk_color_parse("#fff", &color);
    gdk_colormap_alloc_color(colormap, &color, FALSE, TRUE);
    gdk_gc_set_foreground(gc2, &color);
    //.

    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_signal_connect(G_OBJECT(drawer), "expose_event", G_CALLBACK(on_expose_event), NULL);

    //**/mu = g_mutex_new();
    //Run the problematic thread!
    g_thread_create(func, GTK_WIDGET(drawer)->window, FALSE, NULL);

    gdk_threads_enter();
    gtk_main();
    gdk_threads_leave();

    //**/g_mutex_free(mu);
    return 0;
}

コンパイル:

gcc -g -o example update_widget.c `pkg-config --libs --cflags gtk+-2.0 gthread-2.0`

更新 2 :

config.logのコンパイルを確認glibしたところ、以下の単語が見つかりました。

configure:26678: WARNING: I can't find the MACRO to enable thread safety on your
                platform (normally it's _REENTRANT). I'll not use any flag on
                compilation now, but then your programs might not work.
                Please provide information on how it is done on your system.

スレッド機能に影響はありますか?

私のコンパイル用の構成glibは次のとおりです。

export CFLAGS="-march=i686"
./configure --prefix=$HOME/gtk+$GTK_VERSION --with-threads=win32 --with-pcre=internal
make
make install
4

0 に答える 0