Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QString to C string -> Fortran

QString to C string -> Fortran

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 8 Posters 1.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ad1170A Offline
    ad1170A Offline
    ad1170
    wrote on last edited by ad1170
    #4

    IMHO the safe way to do that can be:

    1. Convert the strings as you mentioned in your code above.
    2. Allocate memory for your string like below:
    char *str = new char[qbytearray.size()+1];
    strcpy(str, qbytearray.constData());
    
    1. Than call your Fortran function.
    2. Delete the allocated buffers after the Fortran function was executed (delete[] str).
    Christian EhrlicherC artwawA 2 Replies Last reply
    0
    • ad1170A ad1170

      IMHO the safe way to do that can be:

      1. Convert the strings as you mentioned in your code above.
      2. Allocate memory for your string like below:
      char *str = new char[qbytearray.size()+1];
      strcpy(str, qbytearray.constData());
      
      1. Than call your Fortran function.
      2. Delete the allocated buffers after the Fortran function was executed (delete[] str).
      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by Christian Ehrlicher
      #5

      @ad1170 said in QString to C string -> Fortran:

      IMHO the safe way to do that can be:

      QByteArray is much better since you can't forget the deallocation...

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      ad1170A 1 Reply Last reply
      4
      • ad1170A ad1170

        IMHO the safe way to do that can be:

        1. Convert the strings as you mentioned in your code above.
        2. Allocate memory for your string like below:
        char *str = new char[qbytearray.size()+1];
        strcpy(str, qbytearray.constData());
        
        1. Than call your Fortran function.
        2. Delete the allocated buffers after the Fortran function was executed (delete[] str).
        artwawA Offline
        artwawA Offline
        artwaw
        wrote on last edited by
        #6

        @ad1170 In addition to @Christian-Ehrlicher - you don't need +1 to the size() of QByteArray as this method already returns +1 for \0 char. And yes, QByteArray is much, much safer.

        For more information please re-read.

        Kind Regards,
        Artur

        JonBJ 1 Reply Last reply
        2
        • G gibbogle

          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.

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by jeremy_k
          #7

          @gibbogle said in QString to C string -> Fortran:

          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();

          QString::toLocal8Bit:

          If this string contains any characters that cannot be encoded in the locale, the returned byte array is undefined. Those characters may be suppressed or replaced by another.
          

          Do the locales or QString contents differ between the two machines?

          cstr1 = ba.data();
          ba = qstr2.toLocal8Bit();
          cstr2 = ba.data();
          ...
          execute(&ncpu,str1,&len1,str2,&len2,&res);
          

          QByteArray::data:

          The pointer remains valid as long as the byte array isn't reallocated or destroyed
          

          cstr1 becomes an unsafe pointer when ba is overwritten with the return value of qstr2.toLocal8Bit(). @koahnig's suggestion to use a QByteArray per QString should fix this.

          One question is whether I should be using const char * rather than char *.

          It's not a bad idea. There's also QByteArray::constData()

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          3
          • artwawA artwaw

            @ad1170 In addition to @Christian-Ehrlicher - you don't need +1 to the size() of QByteArray as this method already returns +1 for \0 char. And yes, QByteArray is much, much safer.

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #8

            @artwaw said in QString to C string -> Fortran:

            @ad1170 In addition to @Christian-Ehrlicher - you don't need +1 to the size() of QByteArray as this method already returns +1 for \0 char.

            Although I see @kshegunov & @SGaist have up-voted this, you're all wrong! :) You have to read https://doc.qt.io/qt-5/qbytearray.html#size carefully. Although it is true that QByteArray (usually) adds a \0 at the end of the byte array, it adds at index byteArray[byteArray.size()], i.e. 1 beyond the length returned by QByteArray::size():

            The last byte in the byte array is at position size() - 1. In addition, QByteArray ensures that the byte at position size() is always '\0', so that you can use the return value of data() and constData() as arguments to functions that expect '\0'-terminated strings

            QByteArray::size() returns the length without the extra terminating \0. That means that to copy it as a string you must indeed allocate char *str = new char[qbytearray.size()+1]; as @ad1170 did. If you don't do the + 1 then the strcpy() will copy the terminating \0 to 1 byte beyond the allocated area, leading to potential nasties...!

            Christian EhrlicherC 1 Reply Last reply
            4
            • JonBJ JonB

              @artwaw said in QString to C string -> Fortran:

              @ad1170 In addition to @Christian-Ehrlicher - you don't need +1 to the size() of QByteArray as this method already returns +1 for \0 char.

              Although I see @kshegunov & @SGaist have up-voted this, you're all wrong! :) You have to read https://doc.qt.io/qt-5/qbytearray.html#size carefully. Although it is true that QByteArray (usually) adds a \0 at the end of the byte array, it adds at index byteArray[byteArray.size()], i.e. 1 beyond the length returned by QByteArray::size():

              The last byte in the byte array is at position size() - 1. In addition, QByteArray ensures that the byte at position size() is always '\0', so that you can use the return value of data() and constData() as arguments to functions that expect '\0'-terminated strings

              QByteArray::size() returns the length without the extra terminating \0. That means that to copy it as a string you must indeed allocate char *str = new char[qbytearray.size()+1]; as @ad1170 did. If you don't do the + 1 then the strcpy() will copy the terminating \0 to 1 byte beyond the allocated area, leading to potential nasties...!

              Christian EhrlicherC Online
              Christian EhrlicherC Online
              Christian Ehrlicher
              Lifetime Qt Champion
              wrote on last edited by
              #9

              @JonB You're right. For new/malloc and strcpy the additional \0 has to be considered.

              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
              Visit the Qt Academy at https://academy.qt.io/catalog

              1 Reply Last reply
              3
              • Christian EhrlicherC Christian Ehrlicher

                @ad1170 said in QString to C string -> Fortran:

                IMHO the safe way to do that can be:

                QByteArray is much better since you can't forget the deallocation...

                ad1170A Offline
                ad1170A Offline
                ad1170
                wrote on last edited by ad1170
                #10

                @Christian-Ehrlicher said in QString to C string -> Fortran:

                @ad1170 said in QString to C string -> Fortran:

                IMHO the safe way to do that can be:
                

                QByteArray is much better since you can't forget the deallocation...

                You are right. Inside Qt, use QByteArray or QString, no question.
                But calling a function with an other language binding or from an other library which is awaiting char *str or const char *str i would prefer to make sure that the function gets what she wants. A plain C convention string with a trailing \0.

                1 Reply Last reply
                0
                • Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by Christian Ehrlicher
                  #11

                  @ad1170 said in QString to C string -> Fortran:

                  But calling a function with an other language binding or from an other library which is awaiting char *str or const char *str i would prefer to make sure that the function gets what she wants.

                  It wantsa char*, it gets one - QByteArray::data() returns a pointer to a char array... it simply useless and error prone (e.g. forgot to call delete) what you suggest.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  3
                  • K koahnig

                    @gibbogle

                    Make two different QByteArray one for each string and try

                    G Offline
                    G Offline
                    gibbogle
                    wrote on last edited by
                    #12

                    @koahnig According to my colleague, the program is now working - your fix was successful.. Thanks.

                    aha_1980A 1 Reply Last reply
                    2
                    • G gibbogle

                      @koahnig According to my colleague, the program is now working - your fix was successful.. Thanks.

                      aha_1980A Offline
                      aha_1980A Offline
                      aha_1980
                      Lifetime Qt Champion
                      wrote on last edited by
                      #13

                      Hi @gibbogle,

                      Glad to hear that. So please mark this topic as SOLVED too.

                      Thanks!

                      Qt has to stay free or it will die.

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved