如何接收使用 dbus 作为信号发送的结构?

Posted

技术标签:

【中文标题】如何接收使用 dbus 作为信号发送的结构?【英文标题】:How to receive a struct which was sent as a signal using dbus? 【发布时间】:2014-03-27 09:13:59 【问题描述】:

我创建了一个可以发送信号(字符串)的程序和一个可以读取该信号的其他应用程序。我使用 dbus api。现在我需要发送一个结构(对象)作为信号。这是代码中最重要的部分(发送):

struct x

   int a;
   char *b;
   int c;
 obj;


DBusMessageIter myMsgItrA, myMsgItrB;
dbus_message_iter_init_append(msg, &myMsgItrA);

dbus_message_iter_open_container(&myMsgItrA, DBUS_TYPE_STRUCT, NULL, &myMsgItrB);

dbus_message_append_basic(&myMsgItrB, DBUS_TYPE_INT32, &obj.a);
dbus_message_append_basic(&myMsgItrB, DBUS_TYPE_STRING, &obj.b);
dbus_message_append_basic(&myMsgItrB, DBUS_TYPE_INT32, &obj.c);

dbus_message_close_container(&myMsgItrA, &myMsgItrB);

如何接收该信号? (我已将 dbus_message_iter_get_basic 用于基本类型)

【问题讨论】:

我假设您将在信号接收器端有一些解组代码来解组​​并以与编组相同的方式解释内容。 【参考方案1】:

为您的消息初始化迭代器并使用它来解析 dbus 签名的各个元素。使用 dbus_message_iter_next 移动到 dbus 消息的下一个单个元素,使用 dbus_message_iter_recurse 进入一个复杂的单个元素。

例如:考虑一个签名 s(iuais)。单个元素是 s 和 (iuais)。 使用 dbus_message_iter_init 初始化***迭代器。

使用 dbus_message_iter_next 从 s 移动到 (iuais)。

将迭代器指向 (iuais) 后,使用 dbus_message_iter_recurse 为该元素初始化一个子迭代器,并使用子迭代器进一步解析。

对于签名(isi),解析如下所示

DBusMessageIter rootIter;
dbus_message_iter_init(msg, &rootIter);

if (DBUS_TYPE_STRUCT == dbus_message_iter_get_arg_type(&rootIter))//Get type of argument

   //Initialize iterator for struct
   DBusMessageIter structIter;
   dbus_message_iter_recurse(&rootIter, &structIter);

    //Argument 1 is int32
    if (DBUS_TYPE_INT32 == dbus_message_iter_get_arg_type(&structIter))
    
      int a;
      dbus_message_iter_get_basic(&structIter, &a);//Read integer
      dbus_message_iter_next(&structIter);//Go to next argument of structiter
      //Arg 2 should be a string

  if (DBUS_TYPE_STRING == dbus_message_iter_get_arg_type(&structIter))
  
         char* str = NULL; 
         dbus_message_iter_get_basic(&structIter, &str);//this function is used to read basic dbus types like int, string etc. 
         dbus_message_iter_next(&structIter);//Go to next argument of root iter

     //Argument 3 is int32
         if (DBUS_TYPE_INT32 == dbus_message_iter_get_arg_type(&structIter))
         
        int c;
        dbus_message_iter_get_basic(&structIter, &c);//Read integer
        //PARSING SHOULD END HERE ON SUCCESS
         
        
    
   

【讨论】:

以上是关于如何接收使用 dbus 作为信号发送的结构?的主要内容,如果未能解决你的问题,请参考以下文章

如何确定 DBus 消息中“结构数组”的长度?

dbus 信号中收到的消息与发送的数据不匹配

用python接收dbus信号

如何使用java接收dbus信号'org.gtk.Private.RemoteVolumeMonitor.DriveConnected'?

DBus Glib 发送信号 - 没有发出信号

如何从命令行发出 dbus 信号