[SOLVED]QByteArray, pointer as data



  • Hi!

    I'm looking for a way how to send a pointer via QByteArray class ( sent with drag and drop event).

    I can't get correct value when casting data back to pointer.
    In current (working) code I'm converting address to string, and on the other side back to pointer. Which is extremely slow, and don't even want to know how stable in real life ( it hasn't crashed, yet).

    If someone could please provide code snippet/required methods or recommend an alternative to my problem.

    I've tried with QByteArray::fromRawData(), QByteArray::simplified(), reading with QDataStream and a few other ways, but all unsuccessful.

    And after long summer of C# I'm finally back at C++ and Qt :)

    Regards,
    Jake



  • i don't know what's really the aim doing such unstable job since pointers would be recreated or deleted anytime. anyway you may do something like this
    @
    QWidget *SOURCE=new QWidget();

    quintptr address=(quintptr)SOURCE;
    
    QByteArray b(QString::number(address).toAscii());
    
    QWidget *recover=(QWidget*)b.toULongLong();
    recover->show();
    

    @

    Edited: int data type has changed to quintptr to avoid problems on different platforms


  • Moderators

    Could you explain your needs, and why you want to convert the pointer into bytes?

    Personally, I don't think QByteArray is a good choice. For one thing, you need to cast a pointer (which is essentially an integer) into an array of chars, like Mohsen has shown; there are nicer ways to store a pointer. Also, pointers can have different sizes on different machines -- usually 4 bytes on a 32-bit PC and 8 bytes on a 64-bit PC, but these sizes aren't guaranteed.

    If you need to send multiple pointers at the same time, I recommend storing them in a QVector, as no casting is required. If you only need to send one pointer at a time, you could just send the pointer directly.

    QVector example:
    @
    MyObject *obj1 = new MyObject();
    MyObject *obj2 = new MyObject();
    MyObject *obj3 = new MyObject();

    QVector<MyObject*> vectorOfPointers;
    vectorOfPointers << obj1 << obj2 << obj3;

    ...

    MyObject* retrievedObj1 = vectorOfPointers[0];
    MyObject* retrievedObj2 = vectorOfPointers[1];
    MyObject* retrievedObj3 = vectorOfPointers[2];
    @



  • [quote author="Mohsen" date="1348287297"]i don't know what's really the aim doing such unstable job since pointers would be recreated or deleted anytime. anyway you may do something like this
    @ int address=(int)SOURCE;
    @[/quote]

    This will lead to problems on different architectures (32-/64-Bit). Use quintptr instead.



  • bq. Could you explain your needs, and why you want to convert the pointer into bytes? bq.

    I need it because data will be sent via drag and drop event, where data is sent as QByteArray.

    This pointers will stay in memory as long as the program remains open. So there won't be a problem with pointers being created or deleted.

    And there shouldn't be a problem in different architectures. Program compiled as 32-bit will be 32-bit even on 64-bit machines.

    @Mohsen
    You solution works perfectly. Thanks!

    Regards,
    Jake



  • [quote author="Jake007" date="1348315792"]
    And there shouldn't be a problem in different architectures. Program compiled as 32-bit will be 32-bit even on 64-bit machines.
    @Mohsen
    You solution works perfectly. Thanks![/quote]

    Well "there shouldn't be a problem" says it all. Why introduce the potential to fail in future releases when you decide you might want native 64-bit applications, in a time where you've long forgotten about how you pass those pointers around. Just use quintptr like I proposed. Everything else stays the same, it just has benefits: it's much more future-proof and the programmer's intention is more clear than with int.



  • Because int in 64-bit compile is 8 Bytes large :). As much as a pointer.

    And I considered your proposal the first time and used it in Mohsen's solution :).

    Regards,
    Jake


  • Moderators

    Actually IIRC a int is defined to be at least 16bit long... so storing a pointer in an int is relying on undefined behavior -- even on 32bit machines!

    Relying on undefined behavior is giving the compiler a free hand to break (== optimize) your code however it sees fit! So even if your code works today, it might break whenever you upgrade your compiler...



  • What size int is and what the machine word length is are unrelated. It just so happened that "int" happens to be 32bit in most common architectures, but "quintptr":http://qt-project.org/doc/qt-4.8/qtglobal.html#quintptr-typedef is "guaranteed to be the same size as a pointer on all platforms supported by Qt."



  • [quote author="Jake007" date="1348315792"]
    @Mohsen
    You solution works perfectly. Thanks!
    [/quote]
    you're welcome

    [quote author="DerManu" date="1348314572"]
    This will lead to problems on different architectures (32-/64-Bit). Use quintptr instead.[/quote]
    you're right. that was only an example. you would try it with quintptr



  • [quote author="Jake007" date="1348318060"]Because int in 64-bit compile is 8 Bytes large :). As much as a pointer.

    And I considered your proposal the first time and used it in Mohsen's solution :).

    Regards,
    Jake[/quote]

    Whatever. If people deliberately chose to write bad software, I can't change it, and it explains alot of what's going on in the software world. Your assumption about ints on 64 bit is wrong. See (L)LP64 data model.



  • It's not an assumption. sizeof(int) wrote out 8. Unless I did something wrong (button run instead of build and run etc... happens to me a lot lately).

    I did use quintptr in the first place as suggested. I also wrote that I used it ( unless I awkwardly expressed myself).
    And I don't see the problem with "deliberately".



  • [quote author="Jake007" date="1348336462"]It's not an assumption. sizeof(int) wrote out 8. Unless I did something wrong (button run instead of build and run etc... happens to me a lot lately).[/quote]
    Then you were on a system that uses ILP64 (int, long, pointer are 64 bit). Most 64-bit systems use LP64 (long, pointer are 64 bit) or even LLP64 (longlong, pointer are 64 bit) though.

    [quote author="Jake007" date="1348336462"]I did use quintptr in the first place as suggested. I also wrote that I used it ( unless I awkwardly expressed myself)[/quote]
    Excellent :). I misunderstood it as "I considered your suggestion but used Mohsen's original suggestion with int instead".



  • I just tried sizeof(int) again ( on my computer this time) under x64 compile and the result was 4.
    It's possible that I was on ILP64 system, or that it was my mistake. Probably second. Today I first heard about LP models.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.