[Kde-bindings] [Kde-perl] [PATCH] kdebindings: add perl string marshaller for QByteArray

Richard Dale rdale at foton.es
Thu Oct 12 08:32:19 UTC 2006


Hi Gary

On Wednesday 11 October 2006 20:53, Gary Greene wrote:
> On Monday 09 October 2006 05:40 am, Richard Dale wrote:
> > On Monday 09 October 2006 05:27, Logan Rathbone wrote:
> > > I was always using PerlQt's version of smoke, and I had written a
> > > couple programs using it.  The other day though, I decided to try to
> > > build it against kdebindings's smoke.  However, some of my code broke
> > > because I was using some Qt functions that take QByteArrays, and for
> > > some reason kdebindings's smoke doesn't allow for that and PerlQt's
> > > does.  So this patch seems to add that marshaller into kdebindings's
> > > smoke, and hence unbreaks my code when built against it.
> >
> > The problem is that if you have automatic Perl <--> C++ QByteArray
> > conversion it makes it difficult to use QTextOStreams for instance. When
> > you write to the stream, the underlying QByteArray will be updated, but
> > possibly not the original string you passed. So I found the automatic
> > conversion was more trouble than it's worth. I think a better solution to
> > get the current Smoke lib working with PerlQt is to remove the QByteArray
> > marshalling from handlers.cpp. I'll forward this mail to the kde-bindings
> > and perlqt mailing lists to see what Ashley Winters thinks anyway.
> >
> > -- Richard
> > _______________________________________________
> > Kde-perl mailing list
> > Kde-perl at kde.org
> > https://mail.kde.org/mailman/listinfo/kde-perl
>
> Richard, the only problem with this is that it completely breaks usage of
> QByteArrays for PerlQt. Logan has some apps in PhoeNUX OS that actually use
> QByteArray constructs, thus the reason WHY he patched our build of
> kdebindings to get it working and submitted the patch to kde-devel. The
> definitive plan for PheoNUX is to have the Perl Qt3 / KDE bindings solidly
> working for all apps that we are developing, and then port the codebase of
> PerlQt/PerlKDE to Qt4 / KDE 4 so we get a sane path for when KDE 4 is out.
> This measn that short-changing the binding in this case isn't a good option
> unless we can get QByteArrays working with the marshaller.
You can still use Qt::ByteArrays and they are marshalled find, but you must 
create them with Qt::ByteArray.new in Ruby, and the equivalent in PerlQt.

Here is an example of why you need the QByteArray class in the Smoke library 
as an ordinary class, from Qt4 QtRuby in 
qtruby/rubylib/examples/network/fortuneserver/server.rb:

    def sendFortune
        block = Qt::ByteArray.new
        outf = Qt::DataStream.new(block, Qt::IODevice::WriteOnly)
        outf.version = Qt::DataStream::Qt_4_0
        outf << 0  # Write a 4 byte integer
        outf << @fortunes[rand(@fortunes.length)]
        outf.device.seek(0)
        outf << (block.length - 4)  # 4 bytes is the size of an integer
    
        clientConnection = @tcpServer.nextPendingConnection()
        connect(clientConnection, SIGNAL('disconnected()'),
                clientConnection, SLOT('deleteLater()'))
    
        clientConnection.write(block)
        clientConnection.disconnectFromHost
    end

You open a stream on 'block', write a few things to it, and then later when 
you use 'block' it needs to have been updated. In Ruby, when 'block' was a 
Ruby string and marshalled to a QByteArray before being passed to the 
Qt::DataStream constructor, it meant that the Ruby String never got updated. 
In some other languages like C#  the problem is even worse because Strings 
are immutable, and you would have to use a StringBuffer instance instead, and 
manage to keep it updated in line with the underlying QByteArray. Perhaps in 
Perl you can manage to make it work in the case, I don't know.

Here is how it used to look in QtRuby, and it didn't work:

    def sendFortune
        # Create block as a Ruby String
        block = ""

        # 'block' is marshalled to a C++ QByteArray here:
        outf = Qt::DataStream.new(block, Qt::IODevice::WriteOnly)

        outf.version = Qt::DataStream::Qt_4_0
        outf << 0  # Write a 4 byte integer
        outf << @fortunes[rand(@fortunes.length)]
        outf.device.seek(0)
        outf << (block.length - 4)  # 4 bytes is the size of an integer
    
        clientConnection = @tcpServer.nextPendingConnection()
        connect(clientConnection, SIGNAL('disconnected()'),
                clientConnection, SLOT('deleteLater()'))

        # How is block updated here to reflect the current value of the
        # QByteArray that was passed to the QDataStream constructor
        # above?
        clientConnection.write(block)
        clientConnection.disconnectFromHost
    end

Assuming you're porting PertQt code from Qt3 to Qt4, I think this is a minor 
conversion issue, and I would have thought it shouldn't be too difficult to 
amend the code.

-- Richard



More information about the Kde-bindings mailing list