5

GDBus バインディングを使用して、D-Bus 経由でバイト配列を取得しようとしています。どうすればそれを達成できるか教えてください。グーグルを試しましたが、助けにはなりませんでした。

バイト配列には画像ファイルが含まれているため、charbytearray に変換できません

どんな助けも感謝します

4

4 に答える 4

8

type を使用した XML を使用していくつかのテストを行いましたay。これは、変換先の QT バインディング ( で生成qdbusxml2cpp)ではうまく機能しますが、変換先QByteArrayの glib バインディング ( で生成gdbus-codegen)では機能しないgchar *ようです\0。ストリング。ただし、次のことがわかります。

この自動マッピングは、注釈 org.gtk.GDBus.C.ForceGVariant を使用してオフにすることができます。使用するGVariantと、対応するネイティブ C タイプの代わりに a が常に交換されます。ayこの注釈は、NUL バイトが埋め込まれている可能性のあるデータにバイト文字列 (type-string ) を使用する場合に便利です。

これは、https://developer.gnome.org/gio/stable/gdbus-codegen.htmlによると、それを として処理できることを意味しますGVariantorg.gtk.GDBus.C.ForceGVariant <annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>各引数に注釈のタグを追加してこれをテストしたところ、機能しました。

于 2014-07-23T10:40:47.027 に答える
4

実際には、タイプ「ay」を使用する代わりに、「a(y)」を使用できます。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);
}
于 2015-03-18T10:32:24.557 に答える
0

クライアント側では、 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);
}
于 2016-06-10T06:53:28.263 に答える
0

この質問には、データをファイルに書き込んでファイル名を渡す、名前付きパイプを使用して大量のデータを渡すなど、回答にいくつかの良いアイデアがあります。ファイルに書き込み、ファイル名を渡す方法が最も簡単に実装できます。

于 2014-04-10T23:38:41.840 に答える