【问题标题】:Sending a byte array (type `ay`) over D-Bus using GDBus使用 GDBus 通过 D-Bus 发送字节数组(类型为 `ay`)
【发布时间】:2014-05-21 04:21:47
【问题描述】:

我正在尝试使用 GDBus 绑定在 D-Bus 上创建一个字节数组。你能告诉我我怎么能做到这一点。我试过谷歌搜索但没有帮助。

字节数组包含图像文件,因此无法转换为字符字节数组

任何帮助都是appriciated

【问题讨论】:

    标签: c dbus gdbus


    【解决方案1】:

    我使用 XML 进行了一些测试,其中使用了 ay 类型。这适用于 QT 绑定(使用qdbusxml2cpp 生成),它转换为QByteArray,但它似乎不适用于glib 绑定​​(使用gdbus-codegen 生成),它转换为gchar * 和它似乎您丢失了\0 之后的内容 - 因为它以某种方式作为字符串处理。但是你会发现:

    可以通过使用注释 org.gtk.GDBus.C.ForceGVariant 关闭此自动映射 - 如果使用,则始终交换 GVariant 而不是相应的本机 C 类型。当使用字节串(类型字符串ay)处理可能嵌入 NUL 字节的数据时,此注解可能会很方便。

    这意味着根据https://developer.gnome.org/gio/stable/gdbus-codegen.html,您可以将其处理为GVariant。我通过在每个 arg 上添加注释 org.gtk.GDBus.C.ForceGVariant <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/> 的标签来测试这一点,它可以工作。

    【讨论】:

    • 我认为这个是问题的正确答案。我宁愿使用 ''--annotate'' 选项以及 gdbus-codegen 而不是将其添加到 xml 文件 @cyrax 谢谢..!
    • 您能否发布一个带有注释的示例 xml 文件?这对我不起作用。
    • 以防万一其他人对如何从char *创建"ay" GVariant 感到困惑:gchar *data = ...; GBytes *bytes = g_bytes_new(data, data_size); g_variant_new_from_bytes(G_VARIANT_TYPE_BYTESTRING, bytes, TRUE);
    【解决方案2】:

    实际上,您可以使用“a(y)”,而不是使用“ay”类型。 glib 绑定​​会将“a(y)”转换为 GVariant*。

    然后就可以使用“GVariant”处理来处理参数了。

    例如xml文件

    <method name="parsePacket">
      <arg direction="in" name="message" type="a(y)">
        <doc>
          <line>type: const Uint8 *</line>
        </doc>
      </arg>
    </method>
    

    生成的方法:

    gboolean (*handle_parse_packet) (
    IDbusObject *object, GDBusMethodInvocation *invocation, GVariant *arg_message);
    
    gboolean idbusobject_call_parse_packet_sync (
       IDbusObject *proxy,
       GVariant *arg_message,
       GCancellable *cancellable,
      GError **error);
    

    您可以使用“GVariant”方法提取和插入数据。

    在客户端插入数据:

    void parsePacket (unsigned char* arg_message, guint16 arg_length)
    {
        GVariantBuilder *builder;
        GVariant *value;
    
        builder = g_variant_builder_new (G_VARIANT_TYPE ("a(y)"));
        for (int i = 0; i < arg_length; i++)
        {
            g_variant_builder_add (builder, "(y)", arg_message[i]);
        }
        value = g_variant_new ("a(y)", builder);
        g_variant_builder_unref (builder);
    
        idbusobject_call_parse_packet_sync(proxy,
            value,
            NULL,
            NULL);
    }
    

    在服务器端提取数据:

    gboolean handleParsePacket (
        IDbusObject *object,
        GDBusMethodInvocation *invocation,
        GVariant *arg_message)
    {
        unsigned char byteArray[2048];
        int actualLength = 0;
    
        GVariantIter *iter;
        guchar str;
    
        g_variant_get (arg_message, "a(y)", &iter);
        while (g_variant_iter_loop (iter, "(y)", &str))
        {
            byteArray[actualLength++] = str;
        }
        g_variant_iter_free (iter);
    
        idbusobject_complete_parse_packet( object, invocation);
    
        return (TRUE);
    }
    

    【讨论】:

    • 使用类型 a(y) 而不是 ay 是一个 hacky 解决方法;根据 cyrax 的回答,您应该改用 org.gtk.GDBus.C.ForceGVariant 注释。
    【解决方案3】:

    This question 在答案中有一些好主意,包括通过writing the data to a file and passing the filenameusing a named pipe 传递大量数据。写入文件并传递文件名可能是最容易实现的。

    【讨论】:

      【解决方案4】:

      在客户端,您可以通过调用 g_variant_new_from_data() 方法来更轻松地完成:

      GVariant* convertByteArrayToVariant(unsigned char* arg_message, guint16 arg_length)
      {
          return g_variant_new_from_data(
              G_VARIANT_TYPE ("a(y)"),
              arg_message,
              arg_length,
              TRUE,
              NULL,
              NULL);
      }
      

      或者,如果你有一个 GByteArray*,你可以这样做:

      GVariant* convertByteArrayToVariant(GByteArray* array)
      {
          return g_variant_new_from_data(
              G_VARIANT_TYPE ("a(y)"),
              array->data,
              array->len,
              TRUE,
              NULL,
              NULL);
      }
      

      【讨论】:

        猜你喜欢
        • 2013-01-16
        • 1970-01-01
        • 2017-12-20
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 2015-12-25
        • 1970-01-01
        • 2016-09-29
        相关资源
        最近更新 更多