我想实现一个返回文件描述符的DBus服务,但是引发了这个错误:
** (process:3419): WARNING **: Cannot marshal type "(null)" in variant
** (process:3419): CRITICAL **: unable to append OUT arg of type GValue for create_connection: ((GValue*) 0x647730)
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff6fcd5b9 in g_type_check_value ()
从/usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0 我实现的接口是这样的:
<node name="/org/designfu/IceService">
<interface name="org.designfu.IceService">
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="ice_service"/>
<method name="create_connection">
<!-- This is optional, and in this case is redunundant -->
<annotation name="org.freedesktop.DBus.GLib.CSymbol" value="ice_service_create_connection"/>
<arg type="b" name="controlling_mode" direction="in" />
<arg type="b" name="upnp" direction="in" />
<arg type="s" name="dbus_path" direction="out" />
<arg type="s" name="username_fragment" direction="out" />
<arg type="s" name="password" direction="out" />
<arg type="v(h)" name="send_fd" direction="out" />
<arg type="v(h)" name="recv_fd" direction="out" />
</method>
</interface>
</node>
,这是我的实现:
gboolean ice_service_create_connection(IceService *obj,
const gboolean controlling_mode,
const gboolean upnp,
char **dbus_conn_path,
char **username_fragment,
char **password,
GVariant **send_fd,
GVariant **recv_fd,
GError **error)
{
IceConnection *conn;
gboolean res;
conn = g_object_new(ICE_CONNECTION_TYPE,
"controlling-mode", controlling_mode,
"upnp", upnp,
NULL);
/* register dbus path */
char uuid_str[] = "123";
char dbus_path[512];
g_snprintf(dbus_path, 512, "/org/designfu/IceService/object/%s", uuid_str, NULL);
dbus_g_connection_register_g_object(bus, dbus_path, G_OBJECT(conn));
/* set output parameters */
*dbus_conn_path = g_strdup(dbus_path);
res = ice_connection_get_local_credentials(conn, username_fragment, password);
g_assert(res);
*send_fd = g_variant_new("(h)", conn->their_sock[SEND]);
*recv_fd = g_variant_new("(h)", conn->their_sock[RECV]);
g_assert(*send_fd);
g_assert(*recv_fd);
return TRUE;
}
如果我省略send_fd和recv_fd输出参数,这些函数就会像魅力一样工作。然而,不知何故,我在将文件描述符传递给dbus时出错了。
使用
创建描述符 int domain = AF_LOCAL;
int type = SOCK_STREAM;
int protocol = 0;
err = socketpair(domain, type, protocol, sock);
有人知道这里出了什么问题吗?
v(h)
看起来不像一个有效的DBus类型签名,你确定你不是指(h)
吗?