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

Yaohan Chen yaohan.chen at gmail.com
Fri Feb 24 18:29:05 UTC 2012


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