B4R Question Converting an array to a string

janderkan

Well-Known Member
Licensed User
Longtime User
Years ago I had the same problem and it was solved as you can see in this post
https://www.b4x.com/android/forum/t...eeprom-in-mqtt-initialize2.72492/#post-461148

Now I have updated to Arduino 2.3.4 and B4R 4.0 (I dont know if this is the problem, because I have been away from B4R for some time)

When I try to use ObjectCopy , that was part of the solution , I get a 'Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled.'
I can only copy array to array, not string to string.

That leaves me with a problem with Mqtt library as you can see in this post
https://www.b4x.com/android/forum/threads/how-to-use-a-string-from-eeprom-in-mqtt-initialize2.72492/

I have tried to copy the eeprom data to a GlobalStore but the problem with Mqtt library remains.

Mqtt library needs a literal string and byteconverter.StringFromBytes returns a dynamic string.

Anyone have any ideas and I will be very happy.
 
Solution
Modifying the string literals is problematic.

Solution based on global store, storing a null terminated string:
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Private GlobalString As String
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Dim b() As Byte = "sdhfjksd hfksdhfjksd sdjkf sdjkf hsdjkf"
    CopyBytesToGlobalString(b)    
    Log(GlobalString)
End Sub

Private Sub CopyBytesToGlobalString (b() As Byte)
    Dim b2(b.Length + 1) As Byte
    For i = 0 To b.Length - 1
        b2(i) = b(i)
    Next
    b2(i) = 0
    GlobalStore.Put(0, b2)
    RunNative("SetStringFromZeroTermBytes", GlobalStore.Slot0)
End Sub

#if C
void SetStringFromZeroTermBytes (B4R::Object* o) {
   b4r_main::_globalstring->data = (const...

emexes

Expert
Licensed User
Does your app from 2016 still compile and run without that error, in the updated Arduino and B4R environments?

as in, trying to narrow down whether the new error is due to:

1/ something different about the development environments, or
2/ something different about your code
 
Last edited:
Upvote 0

emexes

Expert
Licensed User
When I try to use ObjectCopy , that was part of the solution , I get a 'Guru Meditation Error: Core 1 panic'ed (LoadStoreError). Exception was unhandled.'
I can only copy array to array, not string to string.

Are you saying that this code that
takes a dynamic string and copies it to a global variable:
B4X:
Sub Process_Globals
   Public Serial1 As Serial
   Private bc As ByteConverter
   Private GlobalString As String = "000000000000000000000000" 'must be long enough to hold the string
End Sub

Private Sub AppStart
   Serial1.Initialize(115200)
   Dim DynamicString As String = bc.StringFromBytes("m21.cloudmqtt.com".GetBytes)
   bc.ObjectCopy(DynamicString, GlobalString, DynamicString.Length + 1)
   'Now you can use GlobalString
End Sub

no longer works?
 
Last edited:
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
Yes , the only problem for now is the object copy.
Yes , the short snippet from Erel does create a panic when trying to copy a string to a string.
 
Upvote 0

emexes

Expert
Licensed User
Yes , the short snippet from Erel does create a panic when trying to copy a string to a string.

I don't have B4R installed here, and so I can't test it.

But I know that when strange things happen during programming, and especially if there are deadlines creeping up,, it is easy to miss simple checks.

The first check here would be to start a brand new empty app and test Erel's snippet just by itself. If that also causes the same error, when that error didn't happen with the previous Arduino and B4R versions, then either there is a bug in one of those that Erel will fix, or a change in one of those that I'm sure Erel or another B4R expert will produce an updated snipped to work around whatever's changed.

That requirement that the string literals need to be unique, is a bit of a trap. Double-check those in your code. Make sure they are completely different so that there is no way that optimisation can possibly use one string in memory for two (supposedly) separate strings. It's a good optimisation, but only as long as the strings are constant and never get changed.
 
Last edited:
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
I did a brand new empty app, and the snippet fail.
I hope the right person will see this and test it.

Jan
 
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
This snippet works on Arduino Uno and Esp8266, but not on ESP32.

Espressif has changed their board packet before.
In 2024 Peacemaker updated the Esp32Extras library because they changed pin names.
https://www.b4x.com/android/forum/threads/esp32extras-library.106766/

In my project the rCan library stopped working when the board packet changed to version 3.x.x (2.0.17 is OK)
https://www.b4x.com/android/forum/threads/rcan-library.120832/

I have tried to change the board packet to version 1.0.6 , but the ObjectCopy still fails.
I have not tried an earlier version of B4R and not an earlier version of Arduino.
But I know that it worked on Arduino1 and B4R 3
 

Attachments

  • TestObjectCopy.zip
    1 KB · Views: 74
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Modifying the string literals is problematic.

Solution based on global store, storing a null terminated string:
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Private GlobalString As String
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Dim b() As Byte = "sdhfjksd hfksdhfjksd sdjkf sdjkf hsdjkf"
    CopyBytesToGlobalString(b)    
    Log(GlobalString)
End Sub

Private Sub CopyBytesToGlobalString (b() As Byte)
    Dim b2(b.Length + 1) As Byte
    For i = 0 To b.Length - 1
        b2(i) = b(i)
    Next
    b2(i) = 0
    GlobalStore.Put(0, b2)
    RunNative("SetStringFromZeroTermBytes", GlobalStore.Slot0)
End Sub

#if C
void SetStringFromZeroTermBytes (B4R::Object* o) {
   b4r_main::_globalstring->data = (const char*)((B4R::Array*)o->data.PointerField)->data;
}
#End if

Note that GlobalStore.Slot0 is used to actually store the data.
 
Upvote 1
Solution

Theera

Expert
Licensed User
Longtime User
What is type of GlobalStore?
 
Upvote 0

janderkan

Well-Known Member
Licensed User
Longtime User
Yes Erels code is working.
I still wonder why object copy is working on Uno and Esp8266 but not on Esp32 after latest update.
I also have some questions about rMqtt and strings but I will create a new thread.
Jan
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
It is easy enough to give up with B4R Strings and start handrolling your own using Byte Arrays
This is definitely the recommended approach, however there are cases where you work with a library that expects a string. The avoid is the solution for such cases.

I still wonder why object copy is working on Uno and Esp8266 but not on Esp32 after latest update.
Constant strings are treated in a special way by the compiler. The compiler assumes that they are constant so can do all kinds of optimizations. Modifying the constant strings is a hack and as we see, doesn't always work.
 
Upvote 0