Chinaunix首页 | 论坛 | 博客
  • 博客访问: 316581
  • 博文数量: 42
  • 博客积分: 451
  • 博客等级: 下士
  • 技术积分: 890
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-03 18:24
文章分类

全部博文(42)

文章存档

2015年(1)

2013年(9)

2012年(19)

2011年(13)

分类: C/C++

2012-08-27 15:23:08

目的:利用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

点击(此处)折叠或打开

  1. #include <glib.h>
  2. #include <dbus/dbus-glib.h>
  3. static gboolean send_ping (DBusConnection *bus);
  4. int
  5. main (int argc, char **argv)
  6. {
  7.   GMainLoop *loop;
  8.   DBusConnection *bus;
  9.   DBusError error;
  10.   /* Create a new event loop to run in */
  11.   loop = g_main_loop_new (NULL, FALSE);
  12.   /* Get a connection to the session bus */
  13.   dbus_error_init (&error);
  14.   bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
  15.   if (!bus) {
  16.     g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
  17.     dbus_error_free (&error);
  18.     return 1;
  19.   }
  20.   /* Set up this connection to work in a GLib event loop */
  21.   dbus_connection_setup_with_g_main (bus, NULL);
  22.   /* Every second call send_ping() with the bus as an argument*/
  23.   g_timeout_add (1000, (GSourceFunc)send_ping, bus);
  24.   /* Start the event loop */
  25.   g_main_loop_run (loop);
  26.   return 0;
  27. }
  28. static gboolean
  29. send_ping (DBusConnection *bus)
  30. {
  31.   DBusMessage *message;
  32.   /* Create a new signal "Ping" on the "com.burtonini.dbus.Signal" interface,
  33.    * from the object "/com/burtonini/dbus/ping". */
  34.   message = dbus_message_new_signal ("/com/burtonini/dbus/ping",
  35.                                      "com.burtonini.dbus.Signal", "Ping");
  36.   /* Append the string "Ping!" to the signal */
  37.   dbus_message_append_args (message,
  38.                             DBUS_TYPE_STRING, "Ping!",
  39.                             DBUS_TYPE_INVALID);
  40.   /* Send the signal */
  41.   dbus_connection_send (bus, message, NULL);
  42.   /* Free the signal now we have finished with it */
  43.   dbus_message_unref (message);
  44.   /* Tell the user we send a signal */
  45.   g_print("Ping!\n");
  46.   /* Return TRUE to tell the event loop we want to be called again */
  47.   return TRUE;
  48. }
清单 2. dbus-ping-listen.c

点击(此处)折叠或打开

  1. #include <glib.h>
  2. #include <dbus/dbus-glib.h>
  3. static DBusHandlerResult signal_filter
  4.       (DBusConnection *connection, DBusMessage *message, void *user_data);
  5. int
  6. main (int argc, char **argv)
  7. {
  8.   GMainLoop *loop;
  9.   DBusConnection *bus;
  10.   DBusError error;
  11.   loop = g_main_loop_new (NULL, FALSE);
  12.   dbus_error_init (&error);
  13.   bus = dbus_bus_get (DBUS_BUS_SESSION, &error);
  14.   if (!bus) {
  15.     g_warning ("Failed to connect to the D-BUS daemon: %s", error.message);
  16.     dbus_error_free (&error);
  17.     return 1;
  18.   }
  19.   dbus_connection_setup_with_g_main (bus, NULL);
  20.   /* listening to messages from all objects as no path is specified */
  21.   dbus_bus_add_match (bus, "type='signal',interface='com.burtonini.dbus.Signal'");
  22.   dbus_connection_add_filter (bus, signal_filter, loop, NULL);
  23.   g_main_loop_run (loop);
  24.   return 0;
  25. }
  26. static DBusHandlerResult
  27. signal_filter (DBusConnection *connection, DBusMessage *message, void *user_data)
  28. {
  29.   /* User data is the event loop we are running in */
  30.   GMainLoop *loop = user_data;
  31.   /* A signal from the bus saying we are about to be disconnected */
  32.   if (dbus_message_is_signal
  33.         (message, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL, "Disconnected")) {
  34.     /* Tell the main loop to quit */
  35.     g_main_loop_quit (loop);
  36.     /* We have handled this message, don't pass it on */
  37.     return DBUS_HANDLER_RESULT_HANDLED;
  38.   }
  39.   /* A Ping signal on the com.burtonini.dbus.Signal interface */
  40.   else if (dbus_message_is_signal (message, "com.burtonini.dbus.Signal", "Ping")) {
  41.     DBusError error;
  42.     char *s;
  43.     dbus_error_init (&error);
  44.     if (dbus_message_get_args
  45.        (message, &error, DBUS_TYPE_STRING, &s, DBUS_TYPE_INVALID)) {
  46.       g_print("Ping received: %s\n", s);
  47.       dbus_free (s);
  48.     } else {
  49.       g_print("Ping received, but error getting message: %s\n", error.message);
  50.       dbus_error_free (&error);
  51.     }
  52.     return DBUS_HANDLER_RESULT_HANDLED;
  53.   }
  54.   return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
  55. }
编译:
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) |
给主人留下些什么吧!~~