下面是 button.c
#include <gtk/gtk.h>
static void close_window (void)
{
gtk_main_quit ();
}
static void print_msg (GtkWidget *button , gpointer data)
{
printf("Hello , world!\n");
}
static void activate (GtkApplication *app , gpointer data)
{
GtkWidget *win;
//申明一个按钮
GtkWidget *button;
//申明一个盒容器,用于容纳按钮,控制大小
GtkWidget *button_box;
win = gtk_application_window_new(app);
gtk_window_set_title(GTK_WINDOW(win) , "Button test");
gtk_window_set_default_size(GTK_WINDOW(win) , 200 , 200);
g_signal_connect (win, "destroy", G_CALLBACK (close_window), NULL);
//创建一个盒容器,并设置水平放置
button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL); //gtk_orientation_horizontal
//将盒容器包含进window中
gtk_container_add(GTK_CONTAINER(win) , button_box);
button = gtk_button_new_with_label("My button");
g_signal_connect (button ,"clicked", G_CALLBACK (print_msg), NULL);
gtk_container_add(GTK_CONTAINER(button_box), button);
//显示window及其所有控件
gtk_widget_show_all(win);
}
int main(int argc , char **argv)
{
GtkApplication *app;
int app_status;
app = gtk_application_new("org.gtk.exmple" , G_APPLICATION_FLAGS_NONE);
g_signal_connect(app , "activate" , G_CALLBACK(activate) , NULL);
app_status = g_application_run(G_APPLICATION(app) , argc , argv);
g_object_unref(app);
return app_status;
}
下面是hook.c
#include <dlfcn.h>
#include<gtk/gtk.h>
void func()
{
printf("NO! I don't want to see you\n");
}
/*#define g_signal_connect(instance, detailed_signal, c_handler, data) \
g_signal_connect_data ((instance), (detailed_signal), (c_handler), (data), NULL, (GConnectFlags) 0)
*/
typedef gulong (*SIGNAL)(gpointer instance, const gchar *detailed_signal,GCallback c_handler, gpointer data ,GClosureNotify destroy_data,GConnectFlags connect_flags);
gulong g_signal_connect_data (gpointer instance, const gchar *detailed_signal,GCallback c_handler, gpointer data,GClosureNotify destroy_data,GConnectFlags connect_flags)
{
static void *handle = NULL;
static SIGNAL old_connect = NULL;
if(!handle)
{
handle = dlopen("libgtk-3.so.0", RTLD_LAZY);
old_connect = (SIGNAL)dlsym(handle, "g_signal_connect_data");
}
if(0 == strcmp("clicked", detailed_signal))
{
return old_connect(instance, detailed_signal, func, data, destroy_data, connect_flags);
}
return old_connect(instance, detailed_signal, c_handler, data, destroy_data, connect_flags);
}
button.c要实现的是点击按钮实现屏幕打印hello word!
我hook住g_signal_connect()函数,把回调函数改成我自己的函数。
gcc button.c -o button `pkg-config --cflags --libs gtk+-3.0`
gcc -fPIC -shared -o hook.so hook.c -ldl `pkg-config --cflags --libs gtk+-3.0`
LD_PRELOAD=$PWD/hook.so button
就可以看到效果了