Qt4-preview-feedback Archive, December 2007
String management in QtScripts
Message 1 in thread
Hi there - I've encountered a couple of oddities when passing strings back and forth from QtScripts that may or may not be due to my own misunderstanding :)
1. I have a script that looks roughly like:
-----
strScriptGlobal = null;
<call C++ to fill a buffer from HTTP>
<get the buffer back during the urlLoaded signal>
function urlLoadedSignalHandler( iID, Bary ) {
Xmsr = new QXmlStreamReader( Bary );
while( !Xmsr.atEnd( ) ) {
Xmsr.readNext( );
...
strScriptGlobal = Xmsr.attributes( )[ 0 ].value( );
... } }
function processAnotherSignalLaterOn( ) {
debugPrint( "This line works, but the next crashes:" );
debugPrint( strScriptGlobal ); }
-----
Here, debugPrint is a C++ function that's been imported into the script engine that just sends its argument to qWarning. Normally this works fine, but in this case, it looks like the string from the QXmlAttribute is being copied by reference instead of value, and by the time the signal processing function is called later on, it's invalid (as a side note, the way QXmlAttributes are wrapped right now, accessing them by name doesn't seem to work, but it looked like that's something that just hasn't been implemented yet?) If I replace the attribute-storing line with:
-----
strScriptGlobal = new String( Xmsr.attributes( )[ 0 ].value( ) );
-----
everything is happy. Triggering a copy on write sort of deal with:
-----
strScriptGlobal = Xmsr.attributes( )[ 0 ].value( ) + "";
-----
also works fine.
2. The standard by-value types seem to work ok with QVariants that come from scripts, but strings show up as UserTypes rather than QStrings. In other words, if I have the following in a script:
-----
someCPPFunction( "I'm a string!" );
-----
and in the C++ function I do:
-----
QScriptValue Scpv = pScpc->argument( 0 );
-----
then Scpv.isVariant( ) returns true, but Scpv.toVariant( ).type( ) returns UserValue. This means that the resulting variant is unaware of the string's memory, and the same sort of premature cleanup can occur as in comment #1 above (i.e. if I store the variant and try to reuse it later, the string's memory has been freed). If I do something like QVariant( Scpv.toString( ) ) instead, things work as expected (since the variant knows it's a string :)
I'm using the 20071118 snapshot, so my apologies if either A) these have changed in the past few days or B) I'm just misunderstanding how the C++ world is intended to play with the QtScript world. The new script functionality is tremendously useful, and a lot of fun :)
Thanks a bunch -
Curtis
To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx
Message 2 in thread
Another interesting tidbit: is it intentional that when some QScriptValue foo contains a QString, foo.toString( ) returns a different result than foo.toVariant( ).tostring( )? In the former case, the returned string contains the "variant(QString..." prefix, whereas the latter gives just the string value. Using a qscriptvalue_cast to QString gives me the former (incorrect?) result.
Thanks -
Curtis
> -----Original Message-----
> From: Curtis Huttenhower [mailto:curtis@xxxxxxxxxxxxxxx]
> Sent: Saturday, December 1, 2007 12:52
> To: qt4-preview-feedback@xxxxxxxxxxxxx
> Subject: String management in QtScripts
>
> Hi there - I've encountered a couple of oddities when passing strings
> back and forth from QtScripts that may or may not be due to my own
> misunderstanding :)
>
> 1. I have a script that looks roughly like:
>
> -----
> strScriptGlobal = null;
> <call C++ to fill a buffer from HTTP>
> <get the buffer back during the urlLoaded signal>
> function urlLoadedSignalHandler( iID, Bary ) {
>
> Xmsr = new QXmlStreamReader( Bary );
> while( !Xmsr.atEnd( ) ) {
> Xmsr.readNext( );
> ...
> strScriptGlobal = Xmsr.attributes( )[ 0 ].value( );
> ... } }
>
> function processAnotherSignalLaterOn( ) {
>
> debugPrint( "This line works, but the next crashes:" );
> debugPrint( strScriptGlobal ); }
> -----
>
> Here, debugPrint is a C++ function that's been imported into the script
> engine that just sends its argument to qWarning. Normally this works
> fine, but in this case, it looks like the string from the QXmlAttribute
> is being copied by reference instead of value, and by the time the signal
> processing function is called later on, it's invalid (as a side note, the
> way QXmlAttributes are wrapped right now, accessing them by name doesn't
> seem to work, but it looked like that's something that just hasn't been
> implemented yet?) If I replace the attribute-storing line with:
>
> -----
> strScriptGlobal = new String( Xmsr.attributes( )[ 0 ].value( ) );
> -----
>
> everything is happy. Triggering a copy on write sort of deal with:
>
> -----
> strScriptGlobal = Xmsr.attributes( )[ 0 ].value( ) + "";
> -----
>
> also works fine.
>
> 2. The standard by-value types seem to work ok with QVariants that come
> from scripts, but strings show up as UserTypes rather than QStrings. In
> other words, if I have the following in a script:
>
> -----
> someCPPFunction( "I'm a string!" );
> -----
>
> and in the C++ function I do:
>
> -----
> QScriptValue Scpv = pScpc->argument( 0 );
> -----
>
> then Scpv.isVariant( ) returns true, but Scpv.toVariant( ).type( )
> returns UserValue. This means that the resulting variant is unaware of
> the string's memory, and the same sort of premature cleanup can occur as
> in comment #1 above (i.e. if I store the variant and try to reuse it
> later, the string's memory has been freed). If I do something like
> QVariant( Scpv.toString( ) ) instead, things work as expected (since the
> variant knows it's a string :)
>
> I'm using the 20071118 snapshot, so my apologies if either A) these have
> changed in the past few days or B) I'm just misunderstanding how the C++
> world is intended to play with the QtScript world. The new script
> functionality is tremendously useful, and a lot of fun :)
>
> Thanks a bunch -
> Curtis
>
>
>
> To unsubscribe - send "unsubscribe" in the subject to qt4-preview-
> feedback-request@xxxxxxxxxxxxx
To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx
Message 3 in thread
Hi Curtis,
Thanks for the feedback. I'll look into the issues you've reported and
get back to you. If you can offer some compilable code that demonstrates
your issues, that would be very helpful.
Regards,
Kent
Curtis Huttenhower wrote:
> Hi there - I've encountered a couple of oddities when passing strings back and forth from QtScripts that may or may not be due to my own misunderstanding :)
>
> 1. I have a script that looks roughly like:
>
> -----
> strScriptGlobal = null;
> <call C++ to fill a buffer from HTTP>
> <get the buffer back during the urlLoaded signal>
> function urlLoadedSignalHandler( iID, Bary ) {
>
> Xmsr = new QXmlStreamReader( Bary );
> while( !Xmsr.atEnd( ) ) {
> Xmsr.readNext( );
> ...
> strScriptGlobal = Xmsr.attributes( )[ 0 ].value( );
> ... } }
>
> function processAnotherSignalLaterOn( ) {
>
> debugPrint( "This line works, but the next crashes:" );
> debugPrint( strScriptGlobal ); }
> -----
>
> Here, debugPrint is a C++ function that's been imported into the script engine that just sends its argument to qWarning. Normally this works fine, but in this case, it looks like the string from the QXmlAttribute is being copied by reference instead of value, and by the time the signal processing function is called later on, it's invalid (as a side note, the way QXmlAttributes are wrapped right now, accessing them by name doesn't seem to work, but it looked like that's something that just hasn't been implemented yet?) If I replace the attribute-storing line with:
>
> -----
> strScriptGlobal = new String( Xmsr.attributes( )[ 0 ].value( ) );
> -----
>
> everything is happy. Triggering a copy on write sort of deal with:
>
> -----
> strScriptGlobal = Xmsr.attributes( )[ 0 ].value( ) + "";
> -----
>
> also works fine.
>
> 2. The standard by-value types seem to work ok with QVariants that come from scripts, but strings show up as UserTypes rather than QStrings. In other words, if I have the following in a script:
>
> -----
> someCPPFunction( "I'm a string!" );
> -----
>
> and in the C++ function I do:
>
> -----
> QScriptValue Scpv = pScpc->argument( 0 );
> -----
>
> then Scpv.isVariant( ) returns true, but Scpv.toVariant( ).type( ) returns UserValue. This means that the resulting variant is unaware of the string's memory, and the same sort of premature cleanup can occur as in comment #1 above (i.e. if I store the variant and try to reuse it later, the string's memory has been freed). If I do something like QVariant( Scpv.toString( ) ) instead, things work as expected (since the variant knows it's a string :)
>
> I'm using the 20071118 snapshot, so my apologies if either A) these have changed in the past few days or B) I'm just misunderstanding how the C++ world is intended to play with the QtScript world. The new script functionality is tremendously useful, and a lot of fun :)
>
> Thanks a bunch -
> Curtis
>
>
>
> To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx
>
>
To unsubscribe - send "unsubscribe" in the subject to qt4-preview-feedback-request@xxxxxxxxxxxxx