Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. QString and Android String are not comparable??
Forum Updated to NodeBB v4.3 + New Features

QString and Android String are not comparable??

Scheduled Pinned Locked Moved Solved Mobile and Embedded
6 Posts 2 Posters 887 Views 1 Watching
  • 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.
  • G Offline
    G Offline
    Gourmet
    wrote on 12 Aug 2019, 20:08 last edited by Gourmet 8 Dec 2019, 20:10
    #1

    Sorry if it was already discussed but I never met this in Internet. I did not find this in Qt Bug report site. Please let me know if I missed something.

    I call Java function like this:

    bool res = QAndroidJniObject::callStaticMethod<jboolean>( PCpath, 
                               "setAccountName", "(Ljava/lang/String;)Z", 
                               QAndroidJniObject::fromString( QString("stringInJavaCode") ).object<jstring>() );
    qWarning()<<res;
    

    The PCpath is static const char* string with proper content. The java method looks like:

        public static boolean setAccountName( String accountName )
        {
            //accountName = "stringInJavaCode";
            if( accountName == "stringInJavaCode" ) // defenitely the same cause it was copy-pasted
            {
                DebugMessage("BUT IT IS TRUE!!!");
                return true;
            }
            return false;
        }
    
    

    And the output:

     : (null):0 ((null)): false
    

    Uncomment accountName assignment and it will print:

     : (null):0 ((null)): "BUT IT IS TRUE!!!"
     : (null):0 ((null)): true
    

    When printing both strings in Java code they are look identically. No difference. I suppose there was left invisible character from QString - the trailing '\0'. Looks like a bug in QAndroidJniObject::fromString() - it must convert QString content clearly. If there is trailing '\0' then it must be removed. Java strings are not null terminated. Backward conversion must add trailing zero.

    J 1 Reply Last reply 13 Aug 2019, 05:50
    1
    • G Gourmet
      12 Aug 2019, 20:08

      Sorry if it was already discussed but I never met this in Internet. I did not find this in Qt Bug report site. Please let me know if I missed something.

      I call Java function like this:

      bool res = QAndroidJniObject::callStaticMethod<jboolean>( PCpath, 
                                 "setAccountName", "(Ljava/lang/String;)Z", 
                                 QAndroidJniObject::fromString( QString("stringInJavaCode") ).object<jstring>() );
      qWarning()<<res;
      

      The PCpath is static const char* string with proper content. The java method looks like:

          public static boolean setAccountName( String accountName )
          {
              //accountName = "stringInJavaCode";
              if( accountName == "stringInJavaCode" ) // defenitely the same cause it was copy-pasted
              {
                  DebugMessage("BUT IT IS TRUE!!!");
                  return true;
              }
              return false;
          }
      
      

      And the output:

       : (null):0 ((null)): false
      

      Uncomment accountName assignment and it will print:

       : (null):0 ((null)): "BUT IT IS TRUE!!!"
       : (null):0 ((null)): true
      

      When printing both strings in Java code they are look identically. No difference. I suppose there was left invisible character from QString - the trailing '\0'. Looks like a bug in QAndroidJniObject::fromString() - it must convert QString content clearly. If there is trailing '\0' then it must be removed. Java strings are not null terminated. Backward conversion must add trailing zero.

      J Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 13 Aug 2019, 05:50 last edited by
      #2

      @gourmet
      interesting, it shouldn't

      this is the fromString function

      QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
      {
          QJNIEnvironmentPrivate env;
          jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
                                              string.length());
          QJNIObjectPrivate obj(res);
          env->DeleteLocalRef(res);
          return obj;
      }
      

      QString::length returns the number of chars that excludes the 0 termination QString("Hello").length() == 5

      what do you get, when you log the string and the length of the string on the Java side?


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      G 1 Reply Last reply 13 Aug 2019, 09:30
      1
      • J J.Hilk
        13 Aug 2019, 05:50

        @gourmet
        interesting, it shouldn't

        this is the fromString function

        QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
        {
            QJNIEnvironmentPrivate env;
            jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
                                                string.length());
            QJNIObjectPrivate obj(res);
            env->DeleteLocalRef(res);
            return obj;
        }
        

        QString::length returns the number of chars that excludes the 0 termination QString("Hello").length() == 5

        what do you get, when you log the string and the length of the string on the Java side?

        G Offline
        G Offline
        Gourmet
        wrote on 13 Aug 2019, 09:30 last edited by Gourmet
        #3

        @j-hilk Of course length() function excludes trailing zero. This is not a visible character and it is not taken in QString comparison.

        @j-hilk said in QString and Android String are not comparable??:

        when you log the string and the length of the string on the Java side?

        Prints equal sizes.

            public static boolean setAccountName( String accountName )
            {
                String line = "stringInJavaCode";
                if( accountName == line ) // defenitely the same cause it was copy-pasted
                {
                    DebugMessage("BUT IT IS TRUE!!!");
                    return true;
                }
                DebugMessage(accountName.length()+" "+line.length());
                return false;
            }
        
        : (null):0 ((null)): "16 16"
        : (null):0 ((null)): false
        
        J 1 Reply Last reply 13 Aug 2019, 09:42
        0
        • G Offline
          G Offline
          Gourmet
          wrote on 13 Aug 2019, 09:37 last edited by
          #4

          Sorry I have find workaround this bug. It stopped my development. I will post official bug report later but now I finish discuss it here.

          1 Reply Last reply
          0
          • G Gourmet
            13 Aug 2019, 09:30

            @j-hilk Of course length() function excludes trailing zero. This is not a visible character and it is not taken in QString comparison.

            @j-hilk said in QString and Android String are not comparable??:

            when you log the string and the length of the string on the Java side?

            Prints equal sizes.

                public static boolean setAccountName( String accountName )
                {
                    String line = "stringInJavaCode";
                    if( accountName == line ) // defenitely the same cause it was copy-pasted
                    {
                        DebugMessage("BUT IT IS TRUE!!!");
                        return true;
                    }
                    DebugMessage(accountName.length()+" "+line.length());
                    return false;
                }
            
            : (null):0 ((null)): "16 16"
            : (null):0 ((null)): false
            
            J Offline
            J Offline
            J.Hilk
            Moderators
            wrote on 13 Aug 2019, 09:42 last edited by J.Hilk
            #5

            @gourmet

            well, to investigate further I suggest the following:

            public static boolean setAccountName( String accountName )
                {
                    String line = "stringInJavaCode";
                    
                   int l1 = accountName.length();
                   int l2 = line.length();
                   int lmin = Math.min(l1, l2); 
              
                    for (int i = 0; i < lmin; i++) { 
                        int str1_ch = (int)str1.charAt(i); 
                        int str2_ch = (int)str2.charAt(i); 
            
                        if(str1_ch != str2_ch)
                           //Diff at index i
                        DebugMessage("Diff here");
            
                    }
                    if( accountName == line ) // defenitely the same cause it was copy-pasted
                    {
                        DebugMessage("BUT IT IS TRUE!!!");
                        return true;
                    }
                    DebugMessage(accountName.length()+" "+line.length());
                    return false;
                }
            

            Actually, in Java, == tests for reference equality (wether they are the same object) and .equals() tests for value equality (wether they are logically equal)

            // These two have the same value
            new String("test").equals("test") // --> true 
            
            // ... but they are not the same object
            new String("test") == "test" // --> false 
            
            // ... neither are these
            new String("test") == new String("test") // --> false 
            

            I guess,
            working as indented...


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            G 1 Reply Last reply 13 Aug 2019, 10:14
            3
            • J J.Hilk
              13 Aug 2019, 09:42

              @gourmet

              well, to investigate further I suggest the following:

              public static boolean setAccountName( String accountName )
                  {
                      String line = "stringInJavaCode";
                      
                     int l1 = accountName.length();
                     int l2 = line.length();
                     int lmin = Math.min(l1, l2); 
                
                      for (int i = 0; i < lmin; i++) { 
                          int str1_ch = (int)str1.charAt(i); 
                          int str2_ch = (int)str2.charAt(i); 
              
                          if(str1_ch != str2_ch)
                             //Diff at index i
                          DebugMessage("Diff here");
              
                      }
                      if( accountName == line ) // defenitely the same cause it was copy-pasted
                      {
                          DebugMessage("BUT IT IS TRUE!!!");
                          return true;
                      }
                      DebugMessage(accountName.length()+" "+line.length());
                      return false;
                  }
              

              Actually, in Java, == tests for reference equality (wether they are the same object) and .equals() tests for value equality (wether they are logically equal)

              // These two have the same value
              new String("test").equals("test") // --> true 
              
              // ... but they are not the same object
              new String("test") == "test" // --> false 
              
              // ... neither are these
              new String("test") == new String("test") // --> false 
              

              I guess,
              working as indented...

              G Offline
              G Offline
              Gourmet
              wrote on 13 Aug 2019, 10:14 last edited by
              #6
              if( accountName.equals( line ) )
              

              This works. Hmmm... No wonder I hate Java.

              1 Reply Last reply
              0

              1/6

              12 Aug 2019, 20:08

              • Login

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