代码之家  ›  专栏  ›  技术社区  ›  Jens Mühlenhoff

为什么信号连接会使socketclient对象无效?

  •  0
  • Jens Mühlenhoff  · 技术社区  · 6 年前

    我试图通过giomm从gio与socketclient类建立tcp/tls连接。

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

    下面是一个精简的示例代码,演示了该问题:

    #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 () 方法被称为i get this console output:

    (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并在第一个错误时停止,但是根据回溯,这是 连接() 方法。

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

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   Jens Mühlenhoff    6 年前

    那里 seems to be a bug 在glibmm或gio中的引用计数中。

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

    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 ();
      }
    }
    
    推荐文章