D-BUS基础编程
第十二章 自由桌面项目
典型的桌面都会有多个应用程序在运行,而且,它们经常需要彼此进行通信。DCOP是一个用于KDE的解决方案,但是它依赖于Qt,所以不能用于其他桌面环境之中。类似的,Bonobo是一个用于GNOME的解决方案,但是非常笨重,因为它是基于 CORBA的。它还依赖于GObject,所以也不能用于GNOME之外。 D-BUS的目标是将DCOP和Bonobo替换为简单的IPC,并集成这两种桌面环境。由于尽可能地减少了D-BUS所需的依赖,所以其他可能会使用 D-BUS的应用程序不用担心引入过多依赖。
D-BUS属于FreeDesktop.org项目的一部分。bus守护进程,没有使用常用的二进制字节流,而是使用了二进制消息的概念,消息由消息头和相应的数据组成。
操作系统的概念: 包括内核、系统守护进程和进程。D-BUS的设计目的:方便同一个桌面会话中的多个应用程序之间的通信;有助于桌面应用程序和操作系统之间的通信。专门用于桌面的,可能不适用于其他方面的应用。
D-BUS总线分类:系统总线和会话总线。
持久的系统总线(system bus),它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。
还将有很多会话总线(session buses),这些总线当用户登录后启动,属于那个用户私有。它是用户的应用程序用来通信的一个会话总线。当然,如果一个应用程序需要接收来自系统总线的消息,它不如直接连接到系统总线----不过,它可以发送的消息将是受限的。
D-BUS基础
API没有绑定到任何一个特定的语言或框架。例如有Glib/Qt/python/C#的D-Bus绑定。
使用D-BUS发送一个消息到总线
C代码
C代码
[url=http://socol.iteye.com/blog/518918#]
# #include //要使用dbus则必须包含此文件
# #include
# #include
#
# /*
# cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-send-hello dbus-send-hello.c && ./dbus-send-hello
# */
#
# int main (int argc, char *argv[])
# {
# DBusError dberr;
# DBusConnection *dbconn;
# DBusMessage *dbmsg;
# char *text;
#
# dbus_error_init (&dberr);
# dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); //代表连接到会话总线,如果需要连接到
# //系统总线,简单把DBUS_BUS_SESSION替换为DBUS_BUS_SYSTEM即可。但是有麻烦,因为
# //系统总线对可以连接到它的用户有限制。可能需要提供一个.service文件指明能连接到某一个指定服务器的权限
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# dbmsg = dbus_message_new_signal ("/com/wiley/test",
# "com.wiley.test",
# "TestSignal");
# /* 函数原型是
# DBusMessage* dbus_message_new_signal (const char *path,
# const char *interface,
# const char *name) */
#
# if (dbmsg == NULL) {
# fprintf (stderr, "Could not create a new signal\n");
# return EXIT_FAILURE;
# }
#
# text = "Hello World";
# dbus_message_append_args (dbmsg, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
#
# dbus_connection_send (dbconn, dbmsg, NULL);
# printf ("Sending signal to D-Bus\n");
#
# dbus_message_unref (dbmsg);
#
# dbus_connection_unref (dbconn);
#
# return EXIT_SUCCESS;
# } #include //要使用dbus则必须包含此文件
#include
#include
/*
cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-send-hello dbus-send-hello.c && ./dbus-send-hello
*/
int main (int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
DBusMessage *dbmsg;
char *text;
dbus_error_init (&dberr);
dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); //代表连接到会话总线,如果需要连接到
//系统总线,简单把DBUS_BUS_SESSION替换为DBUS_BUS_SYSTEM即可。但是有麻烦,因为
//系统总线对可以连接到它的用户有限制。可能需要提供一个.service文件指明能连接到某一个指定服务器的权限
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
dbmsg = dbus_message_new_signal ("/com/wiley/test",
"com.wiley.test",
"TestSignal");
/* 函数原型是
DBusMessage* dbus_message_new_signal (const char *path,
const char *interface,
const char *name) */
if (dbmsg == NULL) {
fprintf (stderr, "Could not create a new signal\n");
return EXIT_FAILURE;
}
text = "Hello World";
dbus_message_append_args (dbmsg, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
dbus_connection_send (dbconn, dbmsg, NULL);
printf ("Sending signal to D-Bus\n");
dbus_message_unref (dbmsg);
dbus_connection_unref (dbconn);
return EXIT_SUCCESS;
}
DBus是与应用程序中的对象而不是应用程序自身进行通信。在GLIB应用程序中,意味着是与GObject及其派生对象通信。应用程序中,这些对象以应用程序地址空间中内存地址的形式传递,将这些内存地址传递给其他应用程序是没有意义的。D-BUS传递对象路径,对象路径类似于文件系统路径,例如 /org/foo/bar等表示Foo Bar应用程序的顶层对象路径。并不是必需的,但是这样做可以避免产生冲突。
发送给一个对象的消息类型:
方法调用(method calls)、方法返回(method returns)、信号(signals) 和错误(errors)。
要执行 D-BUS 对象的方法,您需要向对象发送一个方法调用消息。它将完成一些处理并返回一个方法返回消息或者错误消息。信号的不同之处在于它们不返回任何内容:既没有“信号返回”消息,也没有任何类型的错误消息。
C代码
# dbus_int32_t v_INT32 = 42;
# const char *v_STRING = "Hello World";
# dbus_message_append_args (message,
# DBUS_TYPE_INT32, &v_INT32,
# DBUS_TYPE_STRING, &v_STRING,
# DBUS_TYPE_INVALID);
# const dbus_int32_t array[] = { 1, 2, 3 };
# const dbus_int32_t *v_ARRAY = array;
# dbus_message_append_args (message,
# DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
# DBUS_TYPE_INVALID); dbus_int32_t v_INT32 = 42;
const char *v_STRING = "Hello World";
dbus_message_append_args (message,
DBUS_TYPE_INT32, &v_INT32,
DBUS_TYPE_STRING, &v_STRING,
DBUS_TYPE_INVALID);
const dbus_int32_t array[] = { 1, 2, 3 };
const dbus_int32_t *v_ARRAY = array;
dbus_message_append_args (message,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
DBUS_TYPE_INVALID);
C代码
# dbus_bool_t dbus_connection_send ( DBusConnection * connection,
# DBusMessage * message,
# dbus_uint32_t * serial
# )
# connection the connection.
# message the message to write.
# serial return location for message serial, or NULL if you don't care dbus_bool_t dbus_connection_send ( DBusConnection * connection,
DBusMessage * message,
dbus_uint32_t * serial
)
connection the connection.
message the message to write.
serial return location for message serial, or NULL if you don't care
dbus-get-hello.c :
C代码
# #include
# #include
# #include
#
# /*
# cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-get-hello dbus-get-hello.c && ./dbus-get-hello
# */
#
# static DBusHandlerResult
# filter_func (DBusConnection *connection,
# DBusMessage *message,
# void *user_data)
# {
# dbus_bool_t handled = FALSE;
# char *signal_text = NULL;
#
# if (dbus_message_is_signal (message, "com.wiley.test", "TestSignal")) {
# DBusError dberr;
#
# dbus_error_init (&dberr);
# dbus_message_get_args (message, &dberr, DBUS_TYPE_STRING, &signal_text, DBUS_TYPE_INVALID);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Error getting message args: %s", dberr.message);
# dbus_error_free (&dberr);
# } else {
# DBusConnection *dbconn = (DBusConnection*) user_data;
#
# printf ("Received TestSignal with value of: '%s'\n", signal_text);
#
# handled = TRUE;
# }
# }
#
# return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
# }
#
#
# int main (int argc, char *argv[])
# {
# DBusError dberr;
# DBusConnection *dbconn;
#
# dbus_error_init (&dberr);
# dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# dbus_bus_request_name (dbconn, "com.wiley.test",
# DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "requesting name failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
# return EXIT_FAILURE;
#
# dbus_bus_add_match (dbconn,
# "type='signal',interface='com.wiley.test'",
# &dberr);
#
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Could not match: %s", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
#
# while (dbus_connection_read_write_dispatch (dbconn, -1))
# ; /* empty loop body */
#
#
# return EXIT_SUCCESS;
# } #include
#include
#include
/*
cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-get-hello dbus-get-hello.c && ./dbus-get-hello
*/
static DBusHandlerResult
filter_func (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
dbus_bool_t handled = FALSE;
char *signal_text = NULL;
if (dbus_message_is_signal (message, "com.wiley.test", "TestSignal")) {
DBusError dberr;
dbus_error_init (&dberr);
dbus_message_get_args (message, &dberr, DBUS_TYPE_STRING, &signal_text, DBUS_TYPE_INVALID);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Error getting message args: %s", dberr.message);
dbus_error_free (&dberr);
} else {
DBusConnection *dbconn = (DBusConnection*) user_data;
printf ("Received TestSignal with value of: '%s'\n", signal_text);
handled = TRUE;
}
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int main (int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init (&dberr);
dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
dbus_bus_request_name (dbconn, "com.wiley.test",
DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "requesting name failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
return EXIT_FAILURE;
dbus_bus_add_match (dbconn,
"type='signal',interface='com.wiley.test'",
&dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Could not match: %s", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
while (dbus_connection_read_write_dispatch (dbconn, -1))
; /* empty loop body */
return EXIT_SUCCESS;
}
为了确保正确地接受到信号,我们必须确认拥有com.wiley.test命名空间:
dbus_bus_request_name (dbconn, "com.wiley.test",DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
注册过滤函数:
C代码
# dbus_bool_t dbus_connection_add_filter ( DBusConnection * connection,
# DBusHandleMessageFunction function,
# void * user_data,
# DBusFreeFunction free_data_function
# )
# // connection the connection
# // function function to handle messages
# // user_data user data to pass to the function
# // free_data_function function to use for freeing user data
#
# //Adds a message filter.
#
# if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
# return EXIT_FAILURE; dbus_bool_t dbus_connection_add_filter ( DBusConnection * connection,
DBusHandleMessageFunction function,
void * user_data,
DBusFreeFunction free_data_function
)
// connection the connection
// function function to handle messages
// user_data user data to pass to the function
// free_data_function function to use for freeing user data
//Adds a message filter.
if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
return EXIT_FAILURE;
确保信号不会被忽略,因为通过总线发送的信号有很多,并非所有的应用程序都对它们感兴趣,所以默认情况下,信号将被忽略以阻止“信号泛滥”。
一直监听的代码:
C代码
# dbus_bus_add_match (dbconn,
# "type='signal',interface='com.wiley.test'",
# &dberr);
#
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Could not match: %s", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# } dbus_bus_add_match (dbconn,
"type='signal',interface='com.wiley.test'",
&dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Could not match: %s", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
过滤函数的实现:
C代码
# dbus_bool_t dbus_connection_read_write_dispatch ( DBusConnection * connection,
# int timeout_milliseconds
# )
#
# //This function is intended for use with applications that don't want to //write a main loop and deal with DBusWatch and DBusTimeout.
#
# // An example usage would be:
#
# while (dbus_connection_read_write_dispatch (connection, -1))
# ; // empty loop body dbus_bool_t dbus_connection_read_write_dispatch ( DBusConnection * connection,
int timeout_milliseconds
)
//This function is intended for use with applications that don't want to //write a main loop and deal with DBusWatch and DBusTimeout.
// An example usage would be:
while (dbus_connection_read_write_dispatch (connection, -1))
; // empty loop body
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/111381/showart_2163681.html
第十二章 自由桌面项目
典型的桌面都会有多个应用程序在运行,而且,它们经常需要彼此进行通信。DCOP是一个用于KDE的解决方案,但是它依赖于Qt,所以不能用于其他桌面环境之中。类似的,Bonobo是一个用于GNOME的解决方案,但是非常笨重,因为它是基于 CORBA的。它还依赖于GObject,所以也不能用于GNOME之外。 D-BUS的目标是将DCOP和Bonobo替换为简单的IPC,并集成这两种桌面环境。由于尽可能地减少了D-BUS所需的依赖,所以其他可能会使用 D-BUS的应用程序不用担心引入过多依赖。
D-BUS属于FreeDesktop.org项目的一部分。bus守护进程,没有使用常用的二进制字节流,而是使用了二进制消息的概念,消息由消息头和相应的数据组成。
操作系统的概念: 包括内核、系统守护进程和进程。D-BUS的设计目的:方便同一个桌面会话中的多个应用程序之间的通信;有助于桌面应用程序和操作系统之间的通信。专门用于桌面的,可能不适用于其他方面的应用。
D-BUS总线分类:系统总线和会话总线。
持久的系统总线(system bus),它在引导时就会启动。这个总线由操作系统和后台进程使用,安全性非常好,以使得任意的应用程序不能欺骗系统事件。
还将有很多会话总线(session buses),这些总线当用户登录后启动,属于那个用户私有。它是用户的应用程序用来通信的一个会话总线。当然,如果一个应用程序需要接收来自系统总线的消息,它不如直接连接到系统总线----不过,它可以发送的消息将是受限的。
D-BUS基础
API没有绑定到任何一个特定的语言或框架。例如有Glib/Qt/python/C#的D-Bus绑定。
使用D-BUS发送一个消息到总线
C代码
C代码
[url=http://socol.iteye.com/blog/518918#]
# #include //要使用dbus则必须包含此文件
# #include
# #include
#
# /*
# cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-send-hello dbus-send-hello.c && ./dbus-send-hello
# */
#
# int main (int argc, char *argv[])
# {
# DBusError dberr;
# DBusConnection *dbconn;
# DBusMessage *dbmsg;
# char *text;
#
# dbus_error_init (&dberr);
# dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); //代表连接到会话总线,如果需要连接到
# //系统总线,简单把DBUS_BUS_SESSION替换为DBUS_BUS_SYSTEM即可。但是有麻烦,因为
# //系统总线对可以连接到它的用户有限制。可能需要提供一个.service文件指明能连接到某一个指定服务器的权限
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# dbmsg = dbus_message_new_signal ("/com/wiley/test",
# "com.wiley.test",
# "TestSignal");
# /* 函数原型是
# DBusMessage* dbus_message_new_signal (const char *path,
# const char *interface,
# const char *name) */
#
# if (dbmsg == NULL) {
# fprintf (stderr, "Could not create a new signal\n");
# return EXIT_FAILURE;
# }
#
# text = "Hello World";
# dbus_message_append_args (dbmsg, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
#
# dbus_connection_send (dbconn, dbmsg, NULL);
# printf ("Sending signal to D-Bus\n");
#
# dbus_message_unref (dbmsg);
#
# dbus_connection_unref (dbconn);
#
# return EXIT_SUCCESS;
# } #include //要使用dbus则必须包含此文件
#include
#include
/*
cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-send-hello dbus-send-hello.c && ./dbus-send-hello
*/
int main (int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
DBusMessage *dbmsg;
char *text;
dbus_error_init (&dberr);
dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr); //代表连接到会话总线,如果需要连接到
//系统总线,简单把DBUS_BUS_SESSION替换为DBUS_BUS_SYSTEM即可。但是有麻烦,因为
//系统总线对可以连接到它的用户有限制。可能需要提供一个.service文件指明能连接到某一个指定服务器的权限
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
dbmsg = dbus_message_new_signal ("/com/wiley/test",
"com.wiley.test",
"TestSignal");
/* 函数原型是
DBusMessage* dbus_message_new_signal (const char *path,
const char *interface,
const char *name) */
if (dbmsg == NULL) {
fprintf (stderr, "Could not create a new signal\n");
return EXIT_FAILURE;
}
text = "Hello World";
dbus_message_append_args (dbmsg, DBUS_TYPE_STRING, &text, DBUS_TYPE_INVALID);
dbus_connection_send (dbconn, dbmsg, NULL);
printf ("Sending signal to D-Bus\n");
dbus_message_unref (dbmsg);
dbus_connection_unref (dbconn);
return EXIT_SUCCESS;
}
DBus是与应用程序中的对象而不是应用程序自身进行通信。在GLIB应用程序中,意味着是与GObject及其派生对象通信。应用程序中,这些对象以应用程序地址空间中内存地址的形式传递,将这些内存地址传递给其他应用程序是没有意义的。D-BUS传递对象路径,对象路径类似于文件系统路径,例如 /org/foo/bar等表示Foo Bar应用程序的顶层对象路径。并不是必需的,但是这样做可以避免产生冲突。
发送给一个对象的消息类型:
方法调用(method calls)、方法返回(method returns)、信号(signals) 和错误(errors)。
要执行 D-BUS 对象的方法,您需要向对象发送一个方法调用消息。它将完成一些处理并返回一个方法返回消息或者错误消息。信号的不同之处在于它们不返回任何内容:既没有“信号返回”消息,也没有任何类型的错误消息。
C代码
# dbus_int32_t v_INT32 = 42;
# const char *v_STRING = "Hello World";
# dbus_message_append_args (message,
# DBUS_TYPE_INT32, &v_INT32,
# DBUS_TYPE_STRING, &v_STRING,
# DBUS_TYPE_INVALID);
# const dbus_int32_t array[] = { 1, 2, 3 };
# const dbus_int32_t *v_ARRAY = array;
# dbus_message_append_args (message,
# DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
# DBUS_TYPE_INVALID); dbus_int32_t v_INT32 = 42;
const char *v_STRING = "Hello World";
dbus_message_append_args (message,
DBUS_TYPE_INT32, &v_INT32,
DBUS_TYPE_STRING, &v_STRING,
DBUS_TYPE_INVALID);
const dbus_int32_t array[] = { 1, 2, 3 };
const dbus_int32_t *v_ARRAY = array;
dbus_message_append_args (message,
DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY, 3,
DBUS_TYPE_INVALID);
C代码
# dbus_bool_t dbus_connection_send ( DBusConnection * connection,
# DBusMessage * message,
# dbus_uint32_t * serial
# )
# connection the connection.
# message the message to write.
# serial return location for message serial, or NULL if you don't care dbus_bool_t dbus_connection_send ( DBusConnection * connection,
DBusMessage * message,
dbus_uint32_t * serial
)
connection the connection.
message the message to write.
serial return location for message serial, or NULL if you don't care
dbus-get-hello.c :
C代码
# #include
# #include
# #include
#
# /*
# cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-get-hello dbus-get-hello.c && ./dbus-get-hello
# */
#
# static DBusHandlerResult
# filter_func (DBusConnection *connection,
# DBusMessage *message,
# void *user_data)
# {
# dbus_bool_t handled = FALSE;
# char *signal_text = NULL;
#
# if (dbus_message_is_signal (message, "com.wiley.test", "TestSignal")) {
# DBusError dberr;
#
# dbus_error_init (&dberr);
# dbus_message_get_args (message, &dberr, DBUS_TYPE_STRING, &signal_text, DBUS_TYPE_INVALID);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Error getting message args: %s", dberr.message);
# dbus_error_free (&dberr);
# } else {
# DBusConnection *dbconn = (DBusConnection*) user_data;
#
# printf ("Received TestSignal with value of: '%s'\n", signal_text);
#
# handled = TRUE;
# }
# }
#
# return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
# }
#
#
# int main (int argc, char *argv[])
# {
# DBusError dberr;
# DBusConnection *dbconn;
#
# dbus_error_init (&dberr);
# dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# dbus_bus_request_name (dbconn, "com.wiley.test",
# DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "requesting name failed: %s\n", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
# if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
# return EXIT_FAILURE;
#
# dbus_bus_add_match (dbconn,
# "type='signal',interface='com.wiley.test'",
# &dberr);
#
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Could not match: %s", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# }
#
#
# while (dbus_connection_read_write_dispatch (dbconn, -1))
# ; /* empty loop body */
#
#
# return EXIT_SUCCESS;
# } #include
#include
#include
/*
cc $(pkg-config --cflags --libs dbus-glib-1) -o dbus-get-hello dbus-get-hello.c && ./dbus-get-hello
*/
static DBusHandlerResult
filter_func (DBusConnection *connection,
DBusMessage *message,
void *user_data)
{
dbus_bool_t handled = FALSE;
char *signal_text = NULL;
if (dbus_message_is_signal (message, "com.wiley.test", "TestSignal")) {
DBusError dberr;
dbus_error_init (&dberr);
dbus_message_get_args (message, &dberr, DBUS_TYPE_STRING, &signal_text, DBUS_TYPE_INVALID);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Error getting message args: %s", dberr.message);
dbus_error_free (&dberr);
} else {
DBusConnection *dbconn = (DBusConnection*) user_data;
printf ("Received TestSignal with value of: '%s'\n", signal_text);
handled = TRUE;
}
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
int main (int argc, char *argv[])
{
DBusError dberr;
DBusConnection *dbconn;
dbus_error_init (&dberr);
dbconn = dbus_bus_get (DBUS_BUS_SESSION, &dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "getting session bus failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
dbus_bus_request_name (dbconn, "com.wiley.test",
DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "requesting name failed: %s\n", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
return EXIT_FAILURE;
dbus_bus_add_match (dbconn,
"type='signal',interface='com.wiley.test'",
&dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Could not match: %s", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
while (dbus_connection_read_write_dispatch (dbconn, -1))
; /* empty loop body */
return EXIT_SUCCESS;
}
为了确保正确地接受到信号,我们必须确认拥有com.wiley.test命名空间:
dbus_bus_request_name (dbconn, "com.wiley.test",DBUS_NAME_FLAG_REPLACE_EXISTING, &dberr);
注册过滤函数:
C代码
# dbus_bool_t dbus_connection_add_filter ( DBusConnection * connection,
# DBusHandleMessageFunction function,
# void * user_data,
# DBusFreeFunction free_data_function
# )
# // connection the connection
# // function function to handle messages
# // user_data user data to pass to the function
# // free_data_function function to use for freeing user data
#
# //Adds a message filter.
#
# if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
# return EXIT_FAILURE; dbus_bool_t dbus_connection_add_filter ( DBusConnection * connection,
DBusHandleMessageFunction function,
void * user_data,
DBusFreeFunction free_data_function
)
// connection the connection
// function function to handle messages
// user_data user data to pass to the function
// free_data_function function to use for freeing user data
//Adds a message filter.
if (!dbus_connection_add_filter (dbconn, filter_func, NULL, NULL))
return EXIT_FAILURE;
确保信号不会被忽略,因为通过总线发送的信号有很多,并非所有的应用程序都对它们感兴趣,所以默认情况下,信号将被忽略以阻止“信号泛滥”。
一直监听的代码:
C代码
# dbus_bus_add_match (dbconn,
# "type='signal',interface='com.wiley.test'",
# &dberr);
#
# if (dbus_error_is_set (&dberr)) {
# fprintf (stderr, "Could not match: %s", dberr.message);
# dbus_error_free (&dberr);
# return EXIT_FAILURE;
# } dbus_bus_add_match (dbconn,
"type='signal',interface='com.wiley.test'",
&dberr);
if (dbus_error_is_set (&dberr)) {
fprintf (stderr, "Could not match: %s", dberr.message);
dbus_error_free (&dberr);
return EXIT_FAILURE;
}
过滤函数的实现:
C代码
# dbus_bool_t dbus_connection_read_write_dispatch ( DBusConnection * connection,
# int timeout_milliseconds
# )
#
# //This function is intended for use with applications that don't want to //write a main loop and deal with DBusWatch and DBusTimeout.
#
# // An example usage would be:
#
# while (dbus_connection_read_write_dispatch (connection, -1))
# ; // empty loop body dbus_bool_t dbus_connection_read_write_dispatch ( DBusConnection * connection,
int timeout_milliseconds
)
//This function is intended for use with applications that don't want to //write a main loop and deal with DBusWatch and DBusTimeout.
// An example usage would be:
while (dbus_connection_read_write_dispatch (connection, -1))
; // empty loop body
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u3/111381/showart_2163681.html
相关推荐
- **接口**:D-Bus支持定义接口,用于规范消息格式和处理逻辑,类似于面向对象编程中的接口概念。 - **信号和方法**:信号用于广播信息给感兴趣的订阅者,方法则是客户端和服务端之间的一种同步或异步调用机制。 ...
DBus是Linux系统中的一种消息总线服务,它允许不同的软件组件之间进行相互通信。"d-bus-1.10.16.tar.gz"是一个包含...解压并编译'd-bus-1.10.16.tar.gz',可以深入了解其内部工作原理,并为自定义系统集成提供基础。
`fd-bus`是一个基于C和C++实现的轻量级进程间通信(IPC)框架,它借鉴了Linux系统中的D-Bus设计,但针对更简洁、高效的场景进行了优化。这个开源项目旨在提供一个简单易用、高性能的接口,使得多个进程之间能够高效...
1. D-Bus基础: - 消息总线:D-Bus提供了一个消息传递机制,允许进程之间发送和接收消息。 - 对象路径:每个D-Bus对象都有一个唯一的路径,用于标识服务中的特定实体。 - 接口:定义了对象可以提供的方法、信号和...
首先,我们来了解一下D-Bus的基础概念。D-Bus的核心是消息总线,它作为一个中介,负责转发来自不同进程的消息。这些进程可以作为D-Bus的客户端(clients),通过发送和接收消息与其他客户端或服务端(servers)交互...
根据压缩包内的文件名称"FreeScale Universal Serial Bus.pdf",我们可以推测这是一份PDF格式的文档,内容可能包括理论知识、硬件接口设计、软件编程指南、实例分析以及可能的故障排查等内容。 以下是可能涵盖的...
sdbusplus是OpenBMC中使用的一种库,提供了一个基于D-Bus的IPC(Inter-Process Communication)机制,用于实现进程间的通信。 1. OpenBMC架构 OpenBMC架构主要由多个小进程组成,每个进程负责特定的任务,例如硬件...
----------------------------------- Android 编程基础 1 封面----------------------------------- Android 编程基础 2 开放手机联盟 --Open --Open --Open --Open Handset Handset Handset Handset Alliance ...
其中,I-bus用于内部指令的传输,D-bus用于数据传输,S-bus用于系统总线,而DMA-bus则专门为直接存储器访问(DMA)操作设计,允许外设直接访问内存,而不必经过CPU,以提高系统的性能和效率。 STM32F3系列微控制器...
如果你对Dart和D-Bus有基础,可以深入研究源代码,了解其工作原理,甚至对其进行定制以满足特定需求。对于初学者,这是一个很好的学习资源,可以加深对D-Bus和Dart的理解。 总结来说,DBus导航器是D-Bus生态系统中...
4. **D-Bus编程**:虽然CTK内部处理了大部分D-Bus相关的细节,但理解D-Bus的基本原理和API对于调试和优化可能会有所帮助。 5. **医疗影像知识**:了解DICOM标准和医疗影像处理的基本概念,有助于更好地利用CTK开发...
- **A/D 和 D/A 实验**:模拟信号与数字信号之间的转换。 - **时钟芯片 DS1302 实验**:实现时间和日期的功能。 - **存储芯片 AT24C02 实验**:读写非易失性存储器。 - **步进电机驱动实验**:控制步进电机运动。 - ...
### Linux V4L2 基础编程——直接读写详解 #### 一、V4L2概述 V4L2(Video for Linux Two)是Linux内核为应用程序提供的一个统一接口,用以访问视频输入设备,如摄像头、电视卡等。它允许用户通过简单的API调用来...
- **系统架构**:详细介绍了STM32F4系列MCU的系统架构,包括指令总线(I-bus)、数据总线(D-bus)、系统总线(S-bus)等。 - I-bus(指令总线):负责处理器和程序存储器之间的通信。 - D-bus(数据总线):处理器和...
例如,`hcitool`用于基本蓝牙设备控制,`bluetoothd`是BlueZ的主要后台服务,它管理着系统的蓝牙状态,并对外提供D-Bus接口供其他应用程序调用。 在BlueZ的版本号"3.27"中,我们可以推断这是一款较旧但仍然稳定的...
总结来说,本文从蓝牙技术的基础介绍出发,深入探讨了蓝牙协议栈的具体内容,进而引出了Linux下使用Bluez进行蓝牙编程的关键技术和方法。通过对hci层、L2CAP层和SDP协议的详细介绍,读者可以更好地理解蓝牙通信的...
文档中还涉及了系统架构,包括系统架构的主要部分、内存和总线架构,例如I-bus、D-bus、S-bus、DMA内存总线、DMA外设总线以及以太网、USB OTG、LCD-TFT控制器和DMA2D总线。 STM32F4系列微控制器具有灵活的内存和...
### Linux之V4L2基础编程 #### 一、V4L2简介 V4L2(Video For Linux Two)是Linux内核提供的一种用于访问音视频设备的标准接口。它为用户空间的应用程序提供了与底层硬件交互的方式,使得开发者能够方便地进行视频...
- **S1: D-bus** - 数据总线,用于数据读写操作。 - **S2: S-bus** - 系统总线,主要用于连接系统内部的一些重要组件。 - **S3, S4: DMA-bus** - 直接存储器访问总线,支持高速数据传输,减轻 CPU 负担。 - **Bus ...