【问题标题】:DBus: returning a file descriptorDBus:返回文件描述符
【发布时间】:2023-04-07 03:40:01
【问题描述】:

我想实现一个返回文件描述符的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);

有人知道这里出了什么问题吗?

【问题讨论】:

    标签: glib file-descriptor dbus


    【解决方案1】:

    v(h) 看起来不像一个有效的DBus type signature,你确定你不是指(h)

    【讨论】:

    • 如果我只在 XML 文件中使用 (h)dbus-binding-tool 会引发此错误:process 25994: arguments to dbus_signature_iter_recurse() were incorrect, assertion "dbus_type_is_container (dbus_signature_iter_get_current_type (iter))" failed in file ../../dbus/dbus-signature.c line 213. This is normally a bug in some application using the D-Bus library.
    • 原来dbus-binding-tool 无法处理文件描述符,您应该改用gdbus-codegen!然后它终于可以在不带括号的情况下与h 一起使用!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-11
    • 2015-07-25
    • 1970-01-01
    • 2021-10-09
    • 2023-04-10
    • 1970-01-01
    • 2013-12-11
    相关资源
    最近更新 更多