Results 1 to 7 of 7

Thread: QString -> C string -> Fortran subroutine

  1. #1
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default QString -> C string -> Fortran subroutine

    I have a strange problem that may be created by my lack of C/C++ skills.

    Starting from QStrings, I create two C strings that are passed to a Fortran subroutine. On my Windows 7 machine this works fine - almost all the time. But on a colleagues Windows 10 machine the strings are corrupted every time.

    Here is the declaration of the Fortran subroutine in a DLL:

    void execute(int *,char *, int *,char *, int *, int *);

    Here is the summary of what I'm doing in the Qt code:

    QString qsrt1, qstr2;
    char *cstr1, *cstr2;
    ...
    QByteArray ba = qstr1.toLocal8Bit();
    cstr1 = ba.data();
    ba = qstr2.toLocal8Bit();
    cstr2 = ba.data();
    ...
    execute(&ncpu,str1,&len1,str2,&len2,&res);

    The Fortran code is correct, but on one machine the strings str1 and str2 appear as non-printing characters - random memory, I suspect.
    What makes it very hard to debug is the fact that I almost never see the problem on my old W7 system; I thought it never happened, but then after running the program more than 20 times I got the corrupted string error. There is always the possibility that the problem is elsewhere in the Qt code, but I want to check that I'm not making a mistake with the string conversion. One question is whether I should be using const char * rather than char *.

    Thanks.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QString -> C string -> Fortran subroutine

    Your colleague's Windows 10 machine is probably using unicode strings, which are usually multi-byte character strings. If the input strings are actually just normal 8-bit ASCII represented as two-byte unicode, you should be able to extract every other byte into a C-style string. Try converting your QString to a QLatin1String instead of local 8 bit.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Mar 2008
    Location
    Kraków, Poland
    Posts
    1,536
    Thanked 284 Times in 279 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QString -> C string -> Fortran subroutine

    From QByteArray::data() doc : The pointer remains valid as long as the byte array isn't reallocated or destroyed.
    Look at example from this method doc.

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QString -> C string -> Fortran subroutine

    The pointer remains valid as long as the byte array isn't reallocated or destroyed.
    Ah, missed that in the code. Why would the behavior be different on Win 7?
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QString -> C string -> Fortran subroutine

    The OP's posted code does not pass the cstr1/cstr2 into the FORTRAN function anyway. As written it should not compile, so I guess the OP is actually passing the char pointers.

    As for why it differs in Win 7 versus Win 10. Seems like luck that it works "most of the time" anywhere. For it to work, the second toLocal8Bit() call would have to cause the QByteArray to reallocate its internal buffer to hold the second string (e.g. the second string is longer), and the operating system would have to give it a distinct chunk of memory that was not simply an extension of the original buffer (i.e. not a realloc()), and the OS would have to not allocate the original buffer memory to anyone else or remove it from the process' memory space. Perhaps Win 10 has different memory allocation method or one that deliberately zeros/fills deallocated memory areas. Could also be the difference between a debug/release build or compiler/runtime optimizations for the target CPU.

  6. #6
    Join Date
    Mar 2010
    Location
    Auckland, NZ
    Posts
    121
    Thanks
    9
    Qt products
    Qt4
    Platforms
    MacOS X Windows

    Default Re: QString -> C string -> Fortran subroutine

    Quote Originally Posted by ChrisW67 View Post
    The OP's posted code does not pass the cstr1/cstr2 into the FORTRAN function anyway. As written it should not compile, so I guess the OP is actually passing the char pointers.

    As for why it differs in Win 7 versus Win 10. Seems like luck that it works "most of the time" anywhere. For it to work, the second toLocal8Bit() call would have to cause the QByteArray to reallocate its internal buffer to hold the second string (e.g. the second string is longer), and the operating system would have to give it a distinct chunk of memory that was not simply an extension of the original buffer (i.e. not a realloc()), and the OS would have to not allocate the original buffer memory to anyone else or remove it from the process' memory space. Perhaps Win 10 has different memory allocation method or one that deliberately zeros/fills deallocated memory areas. Could also be the difference between a debug/release build or compiler/runtime optimizations for the target CPU.
    Yes, sorry, the call should be:

    execute(&ncpu,cstr1,&len1,cstr2,&len2,&res);

    I don't use debug builds. Should I create another QByteArray?

    QByteArray ba2 = qstr2.toLocal8Bit();
    cstr2 = ba2.data();

  7. #7
    Join Date
    Jan 2006
    Location
    Bremen, Germany
    Posts
    554
    Thanked 86 Times in 81 Posts
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QString -> C string -> Fortran subroutine

    Quote Originally Posted by gib View Post
    Should I create another QByteArray?
    This is what the documentation and all here (and on forum.qt.io) tells you, yes.

Similar Threads

  1. QT as a GUI for fortran program - ifort
    By kusae in forum Qt Programming
    Replies: 1
    Last Post: 17th October 2015, 14:31
  2. Replies: 8
    Last Post: 25th November 2010, 12:40
  3. std::string to QString
    By baray98 in forum Qt Programming
    Replies: 1
    Last Post: 19th July 2008, 04:56
  4. Need to create QStringList and QVector in FORTRAN
    By praveen in forum Qt Programming
    Replies: 4
    Last Post: 3rd April 2008, 16:20
  5. std::string to QString?
    By Backslash in forum Newbie
    Replies: 4
    Last Post: 1st August 2007, 16:50

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.