目的:利用dbus进行IPC
源码来源:http://www.ibm.com/developerworks/cn/linux/l-dbus.html
环境:桌面系统(因为在CLI情况下报错:** (process:5725): WARNING **: Failed to connect to the D-BUS deamon: /bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.)
清单 1. dbus-ping-send.c- #include <glib.h>
- #include <dbus/dbus-glib.h>
- static gboolean send_ping (DBusConnection *bus);
- int
- main (int argc, char **argv)
- {
- GMainLoop *loop;
- DBusConnection *bus;
- DBusError error;
- /* Create a new event loop to run in */
- loop = g_main_loop_new (NULL, FALSE);
- /* Get a connection to the session bus */
- dbus_error_init (&error);
- bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if (!bus) {
- g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
- dbus_error_free (&error);
- return 1;
- }
- /* Set up this connection to work in a GLib event loop */
- dbus_connection_setup_with_g_main (bus, NULL);
- /* Every second call send_ping() with the bus as an argument*/
- g_timeout_add (1000, (GSourceFunc)send_ping, bus);
- /* Start the event loop */
- g_main_loop_run (loop);
- return 0;
- }
- static gboolean
- send_ping (DBusConnection *bus)
- {
- DBusMessage *message;
- /* Create a new signal "Ping" on the "com.burtonini.dbus.Signal" interface,
- * from the object "/com/burtonini/dbus/ping". */
- message = dbus_message_new_signal ("/com/burtonini/dbus/ping",
- "com.burtonini.dbus.Signal", "Ping");
- /* Append the string "Ping!" to the signal */
- dbus_message_append_args (message,
- DBUS_TYPE_STRING, "Ping!",
- DBUS_TYPE_INVALID);
- /* Send the signal */
- dbus_connection_send (bus, message, NULL);
- /* Free the signal now we have finished with it */
- dbus_message_unref (message);
- /* Tell the user we send a signal */
- g_print("Ping!\n");
- /* Return TRUE to tell the event loop we want to be called again */
- return TRUE;
- }
清单 2. dbus-ping-listen.c- #include <glib.h>
- #include <dbus/dbus-glib.h>
- static DBusHandlerResult signal_filter
- (DBusConnection *connection, DBusMessage *message, void *user_data);
- int
- main (int argc, char **argv)
- {
- GMainLoop *loop;
- DBusConnection *bus;
- DBusError error;
- loop = g_main_loop_new (NULL, FALSE);
- dbus_error_init (&error);
- bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
- if (!bus) {
- g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
- dbus_error_free (&error);
- return 1;
- }
- dbus_connection_setup_with_g_main (bus, NULL);
- /* listening to messages from all objects as no path is specified */
- dbus_bus_add_match (bus, "type='signal',interface='com.burtonini.dbus.Signal'");
- dbus_connection_add_filter (bus, signal_filter, loop, NULL);
- g_main_loop_run (loop);
- return 0;
- }
- static DBusHandlerResult
- signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
- {
- /* User data is the event loop we are running in */
- GMainLoop *loop = user_data;
- /* A signal from the bus saying we are about to be disconnected */
- if (dbus_message_is_signal
- (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) {
- /* Tell the main loop to quit */
- g_main_loop_quit (loop);
- /* We have handled this message, don't pass it on */
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- /* A Ping signal on the com.burtonini.dbus.Signal interface */
- else if (dbus_message_is_signal (message, "com.burtonini.dbus.Signal", "Ping")) {
- DBusError error;
- char *s;
- dbus_error_init (&error);
- if (dbus_message_get_args
- (message, &error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
- g_print("Ping received: %s\n", s);
- dbus_free (s);
- } else {
- g_print("Ping received, but error getting message: %s\n", error.message);
- dbus_error_free (&error);
- }
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
- }
编译:
gcc dbus-ping-send.c -ldbus-glib-1 -o send
gcc dbus-ping-listen.c -ldbus-glib-1 -o listen
各自编译通过
终端1执行./listen
终端2执行./send后:
终端1报错:*** glibc detected *** ./listen: free(): invalid pointer: 0x0804846c ***
经查,是dbus_free(s)一行(清单2第47行)产生的错误。
上网搜索关键词:“free(): invalid pointer:”,集中在两种情况:
可能的情况1:gcc版本问题;
可能的情况2:char *s这个指针指向的内存空间不是通过malloc分配的(malloc分配五大区中的堆区,free只能释放堆区的内存),无法用free函数释放。
情况1不大可靠;
针对情况2,把dbus_free(s)一行删除后,通过send函数无限发送消息给listen,查看listen进程占用的内存:# ps -e|grep listen
5677 pts/4 00:00:01 listen
# top -p 5677
显示该进程内存占用率一直上升,说明内存不断泄漏。
实在不知道该怎么解决了,于是在源代码的基础上,把char *s设为全局变量,并删除dbus_free(s)一行。无限发送消息测试,内存不存在泄漏问题。
算是绕个弯解决了问题。
阅读(2772) | 评论(0) | 转发(0) |