我想实现一个返回文件描述符的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);
有没有人知道这里有什么问题?