我正在尝试使用 GDBus 绑定在 D-Bus 上创建一个字节数组。你能告诉我我怎么能做到这一点。我尝试谷歌搜索但没有帮助。
字节数组包含图像文件,因此无法转换为 charbytearray
任何帮助都会得到帮助
我使用 XML 进行了一些测试,其中我使用了 type ay
。这适用于它转换成的 QT 绑定(用 生成qdbusxml2cpp
),QByteArray
但它似乎不适用于它转换成的 glib 绑定(用 生成gdbus-codegen
),gchar *
而且看起来你失去了之后的东西\0
- 因为它以某种方式被处理为细绳。然而你会发现:
这种自动映射可以通过使用注解 org.gtk.GDBus.C.ForceGVariant 来关闭——如果使用,那么
GVariant
总是交换 a 而不是对应的原生 C 类型。ay
在将字节串(类型字符串)用于可能具有嵌入 NUL 字节的数据时,使用此注释可能会很方便。
这意味着根据https://developer.gnome.org/gio/stable/gdbus-codegen.html,您可以将其处理为GVariant
. 我通过org.gtk.GDBus.C.ForceGVariant
<annotation name="org.gtk.GDBus.C.ForceGVariant" value="true"/>
在每个 arg 上添加注释标签来测试它,它可以工作。
实际上,您可以使用“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);
}
This question在答案中有一些好主意,包括通过将数据写入文件并传递文件名或使用命名管道来传递大量数据。写入文件并传递文件名可能是最容易实现的。
在客户端,您可以通过调用 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);
}