[Kde-bindings] How to unserialize types defined in other Qt apps in QtRuby?

Yaohan Chen yaohan.chen at gmail.com
Sun Feb 26 06:22:48 UTC 2012


I'm getting a segfault when calling #value on the Qt::Variant's produced
from unserializing custom Quassel type objects. As I mentioned in the
previous post, I'm defining and registering the types in a C++ extension.
My code is at https://github.com/hagabaka/Quassel-Ruby , where
lib/quassel/connection.rb and ext/quassel_types.cpp are probably most
relevant.

Below shows the QDebug output of the variant and parts of the backtrace. I
omitted most lines that contained only hex offsets and my code that led
up to this point.

[9] pry(#<Quassel::Connection>)> v
=> #<Qt::Variant:0x92a5518 typeName=BufferInfo>
[10] pry(#<Quassel::Connection>)> Quassel.qt_debug v 
QVariant(BufferInfo, )
=> nil
[11] pry(#<Quassel::Connection>)> v.value
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2350: [BUG] Segmentation fault
ruby 1.9.3p0 (2011-10-30 revision 33570) [i686-linux]

-- Control frame information -----------------------------------------------
c:0038 p:---- s:0136 b:0136 l:000135 d:000135 CFUNC  :qVariantValue
c:0037 p:1797 s:0131 b:0131 l:000130 d:000130 METHOD /usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2350
  ...
c:0018 p:---- s:0057 b:0057 l:000056 d:000056 CFUNC  :call
c:0017 p:0015 s:0054 b:0054 l:000053 d:000053 METHOD /usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2427
c:0016 p:---- s:0050 b:0050 l:000049 d:000049 FINISH
c:0015 p:---- s:0048 b:0048 l:000047 d:000047 CFUNC  :qt_metacall
c:0014 p:---- s:0046 b:0046 l:000045 d:000045 CFUNC  :method_missing
c:0013 p:0013 s:0042 b:0042 l:000041 d:000041 METHOD /usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:469
  ...
-- Ruby level backtrace information ----------------------------------------
bin/quassel-ruby:20:in `<main>'
bin/quassel-ruby:20:in `new'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:459:in `initialize'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:459:in `initialize'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2652:in `run_initializer_block'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2652:in `instance_eval'
bin/quassel-ruby:23:in `block in <main>'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:469:in `exec'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:469:in `method_missing'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:469:in `qt_metacall'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2427:in `invoke'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2427:in `call'
  ...
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2350:in `value'
/usr/lib/ruby/vendor_ruby/1.9.1/Qt/qtruby4.rb:2350:in `qVariantValue'

-- C level backtrace information -------------------------------------------
...
/usr/lib/ruby/site_ruby/1.9.1/i686-linux/qtruby4.so(+0x15aa5) [0xb76ceaa5]
...
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby10InvokeSlot10invokeSlotEv+0x5e) [0xb59d652e]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby10InvokeSlot12mainfunctionEv+0x1b) [0xb59d6a7b]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby11SigSlotBase4nextEv+0x74) [0xb59d42a4]
...
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby17VirtualMethodCall10callMethodEv+0x122) [0xb59d5712]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby14MethodCallBase4nextEv+0x2d) [0xb59d42dd]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby7Binding10callMethodEsPvPN5Smoke9StackItemEb+0x2cd) [0xb5996d2d]
/usr/lib/libsmokeqtcore.so.3(_ZN13__smokeqtcore9x_QObject11qt_metacallEN11QMetaObject4CallEiPPv+0x61) [0xb6166c61]
/usr/lib/libQtCore.so.4(_ZN11QMetaObject8metacallEP7QObjectNS_4CallEiPPv+0x3d) [0xb6ec993d]
/usr/lib/libQtCore.so.4(_ZN11QMetaObject8activateEP7QObjectPKS_iPPv+0x54d) [0xb6ed965d]
/usr/lib/libQtCore.so.4(_ZN9QIODevice9readyReadEv+0x35) [0xb6f29665]
/usr/lib/libQtNetwork.so.4(+0xc92c3) [0xb52692c3]
/usr/lib/libQtNetwork.so.4(+0xb71f9) [0xb52571f9]
/usr/lib/libQtNetwork.so.4(+0xd1ecb) [0xb5271ecb]
/usr/lib/libQtGui.so.4(_ZN19QApplicationPrivate13notify_helperEP7QObjectP6QEvent+0xc4) [0xb63b9964]
/usr/lib/libQtGui.so.4(_ZN12QApplication6notifyEP7QObjectP6QEvent+0x183) [0xb63bed93]
/usr/lib/libsmokeqtgui.so.3(_ZN12__smokeqtgui14x_QApplication6notifyEP7QObjectP6QEvent+0x88) [0xb5dd4978]
/usr/lib/libQtCore.so.4(_ZN16QCoreApplication14notifyInternalEP7QObjectP6QEvent+0x8e) [0xb6ec2afe]
/usr/lib/libQtCore.so.4(+0x1acbe8) [0xb6ef4be8]
/usr/lib/libglib-2.0.so.0(g_main_context_dispatch+0x1df) [0xb57b207f]
/usr/lib/libglib-2.0.so.0(+0x437b0) [0xb57b27b0]
/usr/lib/libglib-2.0.so.0(g_main_context_iteration+0x6a) [0xb57b2a4a]
/usr/lib/libQtCore.so.4(_ZN20QEventDispatcherGlib13processEventsE6QFlagsIN10QEventLoop17ProcessEventsFlagEE+0x67) [0xb6ef55a7]
/usr/lib/libQtGui.so.4(+0x1ed22a) [0xb646d22a]
/usr/lib/libQtCore.so.4(_ZN10QEventLoop13processEventsE6QFlagsINS_17ProcessEventsFlagEE+0x4d) [0xb6ec168d]
/usr/lib/libQtCore.so.4(_ZN10QEventLoop4execE6QFlagsINS_17ProcessEventsFlagEE+0xf9) [0xb6ec1929]
/usr/lib/libQtCore.so.4(_ZN16QCoreApplication4execEv+0x9a) [0xb6ec6b5a]
/usr/lib/libQtGui.so.4(_ZN12QApplication4execEv+0x24) [0xb63b77c4]
/usr/lib/libsmokeqtgui.so.3(_ZN12__smokeqtgui18xcall_QApplicationEsPvPN5Smoke9StackItemE+0x70c) [0xb5dc1f6c]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby10MethodCall10callMethodEv+0x148) [0xb59d75c8]
/usr/lib/libqtruby4shared.so.2(_ZN6QtRuby14MethodCallBase4nextEv+0x2d) [0xb59d42dd]
/usr/lib/libqtruby4shared.so.2(_Z14method_missingiPmm+0x3e3) [0xb599a653]

On Friday, February 24, 2012 01:29:05 PM you wrote:
> Hello,
> 
> I think I am able to unserialize the types in the C++ extension now, by
> calling qRegisterMetaType on them. Now, how can I convert a Qt object in
> C++ extension to Ruby value, e.g. QList -> Array? I could do it myself
> in the extension too, but since this seems to be something QtRuby does,
> is it possible to link to QtRuby in the extension and call its functions
> to do it? If so, is there a way to let it handle the types defined in
> Quassel too, by defining my own conversion method for the types?
> 
> On Thursday, February 23, 2012 06:08:53 AM you wrote:
> > (I'm sorry for the multiple posts; I'm learning new things but not sure
> > if I'm moving in the right direction.)
> > 
> > I added a method in the extension to unserialize data as below, hoping
> > that since it's linked to the Quassel C++ files, it will be able to
> > unserialize the custom types correctly. Unfortunately, looking at QDebug
> > output of the variants, it's still not recognizing the custom types. Also,
> > I don't know how to transfer the unserialized objects from C++ to Ruby,
> > converting them like QtRuby's Qt::Variant#value does.
> > 
> > VALUE unserialize(VALUE self, VALUE string)
> > {
> >   Check_Type(string, T_STRING);
> > 
> >   QByteArray byte_array(RSTRING_PTR(string), RSTRING_LEN(string));
> >   QDataStream data_stream(byte_array);
> >   QVariant variant;
> >   data_stream >> variant;
> > 
> >   // FIXME return a Ruby object for the variant instead of its qDebug
> >   QString output;
> >   QDebug debug(&output);
> > 
> >   debug << variant;
> > 
> >   VALUE result = rb_str_new2(output.toUtf8().data());
> >   rb_enc_associate_index(string, rb_enc_find_index("UTF-8"));
> >   return result;
> > }
> > 
> > 
> > Yaohan Chen
> > 
> > On Thursday, February 23, 2012 02:00:14 AM you wrote:
> > > I compiled several of Quassel's C++ files which define 
> > > the custom types
> > > (most files under "src/common" at 
> > > <http://git.quassel-
> > > irc.org/?p=quassel.git;a=tree;f=src/common;hb=HEAD>),
> > > into an extension, and loaded it in my QtRuby client, 
> > > and unserialization
> > > still doesn't work for the types. I didn't think this 
> > > would be enough,
> > > but I'm not sure what else I need to do now, or if I'm 
> > > going in the right
> > > direction. These C++ files, for example BufferInfo.
> > > {h,cpp}, do define
> > > operator>> and operator<<(QDataStream, type), and use 
> > > Q_DECLARE_METATYPE
> > > and qRegisterMetaType with them.
> > > 
> > > Paolo's link as well as Richard Dale's 
> > > <https://blogs.kde.org/node/2679>
> > > talk about the ability to call a C++ QObject's slots 
> > > in QtRuby, but I'm
> > > not sure how to adapt the technique in my application. 
> > > I don't have
> > > the objects of Quassel types yet, because they're 
> > > serialized in the
> > > stream. If I arbitrarily instantiate one in the 
> > > extension, it doesn't
> > > seem helpful in unserializing other instances. And is 
> > > it possible to
> > > use operator>> as a slot?
> > > 
> > > 
> > > Yaohan Chen
> > > 
> > > On Wednesday, February 22, 2012 04:50:50 PM Arno Rehn 
> > > wrote:
> > > > On Tuesday 21 February 2012 22:35:42 Yaohan Chen 
> > > wrote:
> > > > > Hello,
> > > > > 
> > > > > How can I unserialize objects of types defined in 
> > > a C++ Qt app, through a
> > > > > Qt::DataStream in QtRuby?
> > > > > 
> > > > > I am trying to create a scripting interface for 
> > > the Qt IRC client Quassel
> > > > > <http://quasselirc.org>. Quassel'score connects to 
> > > IRC networks, and its
> > > > > client
> > > > > displays its user interface. The two communicate 
> > > through a socket, sending
> > > > > QVariant maps and lists to each other, and each 
> > > map or list is prefixed
> > > > > with a uint32 indicating its size in the socket. 
> > > My QtRuby client is able
> > > > > to read some of the messages sent by core, but not 
> > > the ones containing
> > > > > types defined by Quassel. These messages show up 
> > > as empty Qt maps. My
> > > > > code is at <https://github.com/hagabaka/Quassel-
> > > Ruby> if it's of any
> > > > > interest.
> > > > > 
> > > > > It seems that normally qRegisterMetaType would be 
> > > used for this, but I'm
> > > > > not sure how to call a template function QtRuby. I 
> > > don't have much
> > > > > experience with C++ Qt programming either, but I 
> > > would appreciate any
> > > > > pointers.
> > > > If the types in question are custom Quassel types, 
> > > you're pretty much out of
> > > > luck, I'm afraid.
> > > > Quassel then uses custom operator<< and operator>> 
> > > for serializing these
> > > > types which the QtRuby runtime can't know about.
> > > > You could create a wrapper C++ library for those 
> > > operators only and then
> > > > call them from Ruby - Paolo has written a nice blog 
> > > entry about easy C++
> > > > interop:
> > > > 
> > > http://pcapriotti.wordpress.com/2010/12/06/effective-
> > > qt-in-ruby-part-3-2/
> > > > 
> > > > I can't think of any other quick solution now.
> > > 
> > 
> 



More information about the Kde-bindings mailing list