GTK+のHelloWorld: コールバック関数の形について

このQ&Aのポイント
  • GTK+のHelloWorldにおけるコールバック関数の形について質問です。
  • g_signal_connectの引数のコールバック関数において、delete_eventはgboolean FUNC(GtkWidget*,GdkEvent*,gpointer)の形をしているのに、helloとdestroyはvoid FUNC(GtkWidget*,gpointer)の形をしています。これらのコールバック関数の形を勝手に決めていいものでしょうか?
  • GTK+のHelloWorldにおいて、コールバック関数の形の決め方について質問です。delete_eventはgboolean FUNC(GtkWidget*,GdkEvent*,gpointer)の形であり、helloとdestroyはvoid FUNC(GtkWidget*,gpointer)の形をしていますが、これらの形式はどのように決まるのでしょうか?
回答を見る
  • ベストアンサー

GTK+のHelloWorldは

static void hello (GtkWidget *widget,gpointer data) { ・・・・・・・・・・・・・・・・ } static gboolean delete_event (GtkWidget *widget,GdkEvent *event,gpointer data) { ・・・・・・・・・・・・・・・・ return FALSE; } static void destroy (GtkWidget *widget,gpointer data) { ・・・・・・・・・・・・・・・・ } int main(int argc,char *argv[]) { GtkWidget *window; GtkWidget *button; ・・・・・・・・・・・・・・・・ g_signal_connect (G_OBJECT(window),"delete_event",G_CALLBACK (delete_event),NULL); g_signal_connect (G_OBJECT (window),"destroy",G_CALLBACK (destroy),NULL); ・・・・・・・・・・・・・・・・ g_signal_connect (G_OBJECT(button),"clicked",G_CALLBACK (hello),NULL); ・・・・・・・・・・・・・・・・ return 0; } ですが g_signal_connectの引数のコールバック関数において delete_eventは gboolean FUNC(GtkWidget*,GdkEvent*,gpointer) の形をしているのに helloとdestroyは void FUNC(GtkWidget*,gpointer) の形をしています これらのコールバック関数の形を勝手に決めていいものでしょうか?

  • keyguy
  • お礼率68% (895/1314)

質問者が選んだベストアンサー

  • ベストアンサー
  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.1

http://www.kitanet.ne.jp/~asler/linux/gtk/ja/gtk_tut_ja-2.html 2.3 シグナルとコールバックの仕組み いろいろある。

keyguy
質問者

お礼

イベントごとにコールバックの形が違っているのですね? どのイベントがどんなコールバック形をしているのかという表みたいなものは無いのでしょうか?

keyguy
質問者

補足

ありがとうございます コンパイラはコールバックの関数形を勝手に決めてしまうと認識できないのでコールバックの関数形は何らかの規則で決まっていると思いますがこのシグナル関数の引数のコールバックの関数形はこの2つだけでしょうか? その識別はイベントが"delete_event"であるかそうでないかの2通りだけでしょうか?

その他の回答 (1)

  • mcWalker
  • ベストアンサー率69% (27/39)
回答No.2

gtk+ はソース・コードが公開されています。 ダウンロードして、眺めた方が早いかと思います。

keyguy
質問者

お礼

ありがとうございます

関連するQ&A

  • Linux GTK+でのコンパイルエラー

    GKT+でプログラミングをしたいと思い、下記のサイトを見ながらサンプルプログラムをコンパイルしたら下のようなエラーが表示されました。原因が全くわからず困っています。わかる方教えてください。 【参考にしたサイト】 http://samidarehetima.web.fc2.com/howtogtk/top.html#toc_1 【コード】 #include <gtk/gtk.h> //ボタンがクリックされたときに呼び出される関数 static void button_clicked(GtkWidget *button, gpointer user_data) { gtk_main_quit(); } int main(int argc, char** argv){ GtkWidget *window; gtk_init(&argc,&argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_widget_set_size_request(window,300,200); { //ボタンを作成する。 GtkWidget *button; button = gtk_button_new_with_label("Quit"); //ボタンをwindowに乗っける。 gtk_container_add(GTK_CONTAINER(window), button); //ボタンにclickedと表示し,押された時はbutton_clicked()を呼び出す。 g_signal_connect (G_OBJECT(button), "clicked" , G_CALLBACK(button_clicked), NULL); } g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); //windowの上にある物も全て表示する。(_allが付くことに注意) gtk_widget_show_all(window); gtk_main(); return 0; } 【エラー】 /tmp/ccmjmPda.o: In function `button_clicked': test.c:(.text+0x7): undefined reference to `gtk_main_quit' /tmp/ccmjmPda.o: In function `main': test.c:(.text+0x25): undefined reference to `gtk_init' test.c:(.text+0x31): undefined reference to `gtk_window_new' test.c:(.text+0x51): undefined reference to `gtk_widget_set_size_request' test.c:(.text+0x5d): undefined reference to `gtk_button_new_with_label' test.c:(.text+0x66): undefined reference to `gtk_container_get_type' test.c:(.text+0x76): undefined reference to `g_type_check_instance_cast' test.c:(.text+0x86): undefined reference to `gtk_container_add' test.c:(.text+0x9f): undefined reference to `g_type_check_instance_cast' test.c:(.text+0xcb): undefined reference to `g_signal_connect_data' test.c:(.text+0xeb): undefined reference to `gtk_main_quit' test.c:(.text+0xff): undefined reference to `g_signal_connect_data' test.c:(.text+0x10b): undefined reference to `gtk_widget_show_all' test.c:(.text+0x110): undefined reference to `gtk_main' collect2: ld はステータス 1 で終了しました

  • gtk2 gladeのc++ビルド

    OpenIndiana に gtk2 library/desktop/gtk2 0.5.11(ビルド5.11-0.151.1.2) glade developer/ui-designer/glade 0.5.11(ビルド 5.11-0.151.1.2) パッケージをインストールして、 NetBeans IDE 7.1をつかって、c++で下記プログラムをビルドしてみようとしたのですが、 ビルドエラーになってしまいました。 #define GTK_DISABLE_DEPRECATED 1 #define LIBGLADE_DISABLE_DEPRECATED 1 #include <gtk/gtk.h> #include <glade/glade.h> G_BEGIN_DECLS void on_button2_clicked(); G_END_DECLS void on_button2_clicked() { printf("clicked!\n"); } int main(int argc, char* argv[]) { GladeXML* xml; GtkWidget* window; gtk_init(&argc, &argv); xml = glade_xml_new("glade_test.glade", NULL, NULL); if (!xml) { printf("glade file error.\n"); return 1; } window = glade_xml_get_widget(xml, "window"); glade_xml_signal_autoconnect(xml); g_object_unref(G_OBJECT(xml)); gtk_widget_show(window); gtk_main(); return 0; } インクルードパス、ライブラリパス等が不足しているのかと思い、 /usr/include/gtk-2.0 へインクルードパスを通してみたのですが、やはりたくさんエラーがでているようでした。 ビルドに必要なincludeパス、ライブラリパス、その他不足しているもの等ございましたら、 ご教授よろしくお願いいたします。

  • 下のソースを参考書をそのまま書いたのですが

    下のソースを参考書をそのまま書いたのですが eclipse環境だと f.show(); のところが推薦されない使われ方 として実行できません 無理やり動作させたところ、エラーが返ってきました どうすれば、f.show(); が有効にできるでしょうか? import java.awt.*; import java.awt.event.*; import java.applet.Applet; public class window { public static void main( String[] args ) { AppFrame f = new AppFrame(); f.setSize( 200, 200 ); f.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e) { System.exit(0); } } ); f.show(); } } class AppFrame extends Frame implements ActionListener { Button b1, b2; labelWindow window; AppFrame() { setLayout( new FlowLayout() ); b1 = new Button( "Display the window" ); add(b1); b1.addActionListener( this ); b2 = new Button( "Hide the window" ); add(b2); b2.addActionListener( this ); window = new labelWindow(this); window.setSize( 300,200 ); window.setLocation( 300, 300 ); } public void actionPerformed( ActionEvent event ) { if( event.getSource() == b1 ) { window.setVisible(true); } if( event.getSource() == b2 ) { window.setVisible(false); } } } class labelWindow extends Window { Label label; labelWindow( AppFrame af ) { super( af ); setLayout( new FlowLayout() ); label = new Label( "Hello from Java!" ); add( label ); } public void paint( Graphics g ) { int width = getSize().width; int heigth = getSize().heigth; g.drawRect( 0, 0, --width, --heigth ); } }

    • ベストアンサー
    • Java
  • DLLの関数呼び出しで引数があるとフリーズしてしまう。

    はじめまして、C言語勉強中の初心者です。 現在、DLLに定義されている関数を呼び出すことを試していますが、うまくいかないので質問させて頂きました。 DLLには2つの関数が定義されています。  1.void Hello()  2.void HelloEx(char *pval); 1の関数を呼び出す場合は異常なく終了するのですが、2の関数を呼び出すと、フリーズしてしまいます。 フリーズする原因が分からないので、教えて頂ければと思います。 以下にソースを掲載します。 因みにコンパイラはBCC5.5.1を使用しています。 ***************************************************** DLL(Hello.c) [bcc32 -WD Hello.c] ***************************************************** #include <windows.h> #include <stdio.h> __declspec(dllexport) void CALLBACK Hello(void) { printf("Hello!\n"); } __declspec(dllexport) void CALLBACK HelloEx(char *pVal) { printf("Hello!%s\n", pVal); } ***************************************************** EXE(HelloTest.c)[bcc32 -L HelloTest.c] ***************************************************** #include <windows.h> #include <stdio.h> typedef void (*Hello)(void); typedef void (*HelloEx)(char*); int main(void) { HMODULE hMod; Hello func; HelloEx funcEx; hMod = LoadLibrary( "Hello.dll" ); if(!hMod) return FALSE; func = (Hello)GetProcAddress( hMod, "Hello"); if(!func) return FALSE; funcEx = (HelloEx)GetProcAddress( hMod, "HelloEx"); if(!funcEx) return FALSE; func(); funcEx("World"); FreeLibrary(hMod); return 0; } *********************************************** 以上

  • プログラムがわかりません

    C言語の本を読んでいるんですが、詰まってしまいました。プログラム自体は単純なのですが #include<stdio.h> void hello(void) { fprintf(stderr,"hello!\n"); } void func(void) { void *buf[10]; static int i; for(i=0;i<10;i++) { buf[i] = hello; } } int main(void) { int buf[100]; func(); return 0; } のスタックオーバーフローのプログラムです。 1. 要素100のint型配列を宣言 2. 関数funcの呼び出し 3. void *buf[10]; まずここでがわかりません。なぜポインタが   でてきたのか?またbufの要素数は100では? 4. buf[i] = hello; のループ    これもわかりません。配列に関数を代入しているのでしょうか?     5.  fprintf(stderr,"hello!\n"); これもまたわかりません。    fprintfの最初の引数は出力先ですが、なぜ標準エラー出力なの   でしょうか? 時間のあるかた解説お願いします。

  • デザパタ シングルトンクラスの実態宣言の場所について

    //-----singleton.h---------------------------------------- // Copyright(C) 2003 Yoshinori Oota All rights reserved. #ifndef SINGLTON #define SINGLTON #include <iostream> #include <string> using namespace std; class Singleton { public: static Singleton* Instance(); static void Destroy(); void nextState(); void printState() const; private: Singleton(); ~Singleton(); static Singleton* theInstance; string value_; }; //ここじゃだめなの? //Singleton* Singleton::theInstance = NULL; #endif //------------------------------------------------------- //-----singleton.cpp--------------------------------------- #include"singleton.h" Singleton* Singleton::theInstance = NULL; Singleton::Singleton() : value_("initial state") { } Singleton::~Singleton() { } Singleton* Singleton::Instance() { if (theInstance == NULL) { theInstance = new Singleton(); } return theInstance; } void Singleton::Destroy() { if (theInstance != NULL) { delete theInstance; theInstance = NULL; } } void Singleton::nextState() { if (value_ == "initial state") { value_ = "second state"; } else if (value_ == "second state") { value_ = "third state"; } else if (value_ == "third state") { value_ = "initial state"; } } void Singleton::printState() const { cout << value_ << endl; } //------------------------------------------------------ //----main.cpp------------------------------------------- #include"singleton.h" int main() { Singleton* theSingleton = Singleton::Instance(); theSingleton->printState(); theSingleton->nextState(); theSingleton->printState(); //デストラクタも隠蔽することにより、2重deleteを防げる Singleton::Destroy(); } //-------------------------------------------------------- デザパタのシングルトンを勉強していたのですが、 実態の宣言(Singleton* Singleton::theInstance = NULL;)はヘッダファイル内だとなぜだめなのでしょうか? さらにprivate修飾がついてるのに、なぜNULLにセットできるでしょう。 参照HP http://www002.upp.sonet.ne.jp/ys_oota/mdp/Singleton/index.htm

  • 参照渡し?

    お世話になります。 下記のソースを実行すると public class ExecMain { public static void main(String[] args) { ObjectLife obj = new ObjectLife(); ObjectLife obj2 = obj; obj = null; System.out.println(obj); System.out.println(obj2); } static class ObjectLife { public ObjectLife() { create(); } public void create() { System.out.println("create calling"); } public void destroy() { System.out.println("destroy calling"); this = null; } } } -------------------- create calling null objectLife.ExecMain$ObjectLife@1b90b39 という実行結果になりました。 「objectLife.ExecMain$ObjectLife@1b90b39」 がnullにならないのはどうしてなのでしょう? また this=null; で自分自身のインスタンスをnullにしようとおもったのですが コンパイルはとおるのですが実行してもなにもおきていないようです。 これはどのように解釈すればよいのでしょうか? 以上よろしくお願いいたします。

    • ベストアンサー
    • Java
  • StringBufferで

    次のソースを実行して、なぜHelloとHello,Worldが出力されるのかがよくわかりません。func()の中でa=bと参照の受け渡しが行われないのでしょうか。 class F{ static void func(StringBuffer a, StringBuffer b){ b.append(", World."); StringBuffer w = a; a = b; b = w; System.out.println("a="+a +" b=" +b); } } class HelloWorld{ public static void main(String args[]){ StringBuffer s1 = new StringBuffer("Hello"); StringBuffer s2 = new StringBuffer("Hello"); F.func(s1, s2); System.out.println(s1); System.out.println(s2); } }

  • コンパイラのバグ?それとも

    下のようなコードを書いて、たとえば java PossibleCompilerMalfunction Hello のように実行すると、 Hello と表示されることを期待していたのですが、 null と表示されてしまいます。 (JDK1.5を使っています) final String t = args[0]; の部分を final String t = "Hello"; のように書き換えると、 Hello と表示されます。 つまり、コンパイル時に「t」の値が決まっていなければ nullになってしまうようです。 これってコンパイラのバグでしょうか。 あるいは私の考えに間違いがあるのでしたら、 指摘していただけるとありがたいです。 public class PossibleCompilerMalfunction { public static void main(String[] args) { final String t = args[0]; MyClass mc = new MyClass() { void foo() { System.out.println(t); } }; } static abstract class MyClass { MyClass() { foo(); } abstract void foo(); } }

    • ベストアンサー
    • Java
  • static付き宣言の初期化

    static付きの宣言をした場合の変数の初期化について教えてください。(ANSI-C) int func(void) { static int si; static char sca[10]; static char *scp; /* 何らかの処理 */ return 0; } このように関数内でstatic付きで宣言したとき、変数はどのように初期化されますか? siは0、sca[0]からsca[9]までは'\0'、scpはNULLで初期化されますか? また、このようなstatic付きの宣言が関数の外にあった場合は、どのように初期化されますか?

専門家に質問してみよう