【问题标题】:Why does signal connection invalidate the SocketClient object?为什么信号连接会使 SocketClient 对象失效?
【发布时间】:2018-06-08 22:46:12
【问题描述】:

我正在尝试通过 giomm 与 Gio 的 SocketClient 类建立 TCP / TLS 连接。

一切都很好,直到我用sigc::ptr_fun () 连接到SocketClient::event_signal () 信号。

这是一个演示问题的精简示例代码:

#include <giomm/error.h>
#include <giomm/init.h>
#include <giomm/networkaddress.h>
#include <giomm/socketclient.h>
#include <glibmm/main.h>
#include <iostream>

void socket_client_event (Gio::SocketClientEvent event,
              const Glib::RefPtr<Gio::SocketConnectable> &connectable,
              const Glib::RefPtr<Gio::IOStream> &connection) {
}

int main () {
  auto loop = Glib::MainLoop::create ();
  Gio::init ();
  auto network_address = Gio::NetworkAddress::create ("www.example.org", 437);
  auto socket_client = Gio::SocketClient::create ();
  socket_client->set_tls (true);
  socket_client->signal_event ().connect (sigc::ptr_fun (&socket_client_event));
  Glib::RefPtr<Gio::SocketConnection> socket_connection;
  try {
    socket_connection = socket_client->connect (network_address);
  }
  catch (const Gio::TlsError &e) {
    std::cerr << e.what (). c_str () << std::endl;
    return 1;
  }
  catch (const Gio::Error &e) {
    std::cerr << e.what (). c_str () << std::endl;
    return 1;
  }

  loop->run ();
}

connect () 方法被调用时,我得到这个控制台输出:

(process:9046): GLib-GIO-CRITICAL **: g_socket_connection_connect: assertion 'G_IS_SOCKET_CONNECTION (connection)' failed

(process:9046): GLib-GObject-CRITICAL **: g_object_unref: assertion 'G_IS_OBJECT (object)' failed

(process:9046): GLib-GObject-CRITICAL **: g_object_get_qdata: assertion 'G_IS_OBJECT (object)' failed

(process:9046): GLib-GObject-CRITICAL **: g_object_get_qdata: assertion 'G_IS_OBJECT (object)' failed

然后一个分段错误使程序死亡。

我已打开 G_DEBUG=all 并在第一个错误处停止,但根据回溯,这是在 connect () 方法中的某处。

奇怪的是,注释掉连接信号处理程序的源代码行可以解决问题。

那么在这里连接信号时我做错了什么?为什么socket客户端连接后无效?

【问题讨论】:

    标签: c++ glib gio libsigc++ glibmm


    【解决方案1】:

    在 glibmm 或 gio 的引用计数中有 seems to be a bug

    如果我在问题消失时手动引用对象:

    void socket_client_event (Gio::SocketClientEvent event,
                  const Glib::RefPtr<Gio::SocketConnectable> &connectable,
                  const Glib::RefPtr<Gio::IOStream> &connection) {
      // Workaround for reference counting problems
      if (connectable) {
        connectable->reference ();
      }
      if (connection) {
        connection->reference ();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-13
      相关资源
      最近更新 更多