MemoryBlock
From Xojo Documentation
A MemoryBlock object allocates a sequence of bytes in memory and manipulates those bytes directly. A MemoryBlock can be passed in place of a Ptr when used in a Declare call.
Properties | ||
|
Constructors | |
|
Class Constants
The following class constant is returned by Size when the size of the MemoryBlock cannot be determined.
Class Constant | Description |
---|---|
SizeUnknown | The size of the MemoryBlock cannot be determined. |
Notes
For 32-bit apps, you can request a maximum of about 2 to 3 GB depending on the OS. Generally Windows is closer to 2GB and Mac/Linux are closer to 3GB. There is no practical limit for 64-bit apps. |
Memoryblocks can be used whenever you need a container for any arbitrary binary data.
Memoryblocks are used when accessing entry points in shared libraries and when making OS calls using the Declare function.
MemoryBlocks supports creating a zero-length MemoryBlock.
The contents of a MemoryBlock can be viewed in the Debugger.
You can initialize a MemoryBlock from a string without using the constructor and declaring its size. For example, the following initializes a MemoryBlock from a String.
You can convert this MemoryBlock back to a String with an assignment statement or a call that accepts a string. This statement converts the MemoryBlock back to a String.
You can also pass this MemoryBlock to a function that expects a String. For example:
OutOfBoundsExceptions with StringValue
Accessing invalid StringValues can raise an OutOfBoundsException. Examples include:
Accessing a MemoryBlock StringValue with a size of 0:
Accessing a MemoryBlockStringValue with a size less than 0:
You will also get an OutOfBoundsException if the StringValue length is less than 0.
Sample Code
String Append Example Project
The FastStringAppend project (included with Xojo: Examples/Advanced/MemoryBlock/FastStringAppend) uses MemoryBlocks to append two strings together as fast as possible. The main window has two TextFields, a PushButton, and a Label for displaying the result.
The user enters strings into the TextFields and clicks the PushButton. The Action event for the PushButton is the following:
// create a New memBlockString
m = New MemBlockString
// add the strings into the memBlockString
m.AppendString(TextField1.Value)
m.AppendString(TextField2.Value)
// retreive the string
Label1.Value = m.GetString
The MemBlockString object is a custom class. It has the properties:
The constructor is:
// while creating long strings by appending to already existing
// strings. It can be a lot quicker than s = s + "more text" if
// you have very long strings
// This is both the size of the original memoryBlock
// but also how much it increases by each time if needed
BufferSize = 100000 // bigger than really needed
mb = New MemoryBlock(BufferSize)
TotalLength = BufferSize
The appendString method is called in the PushButton's Action event:
#Pragma DisableBackgroundTasks
Var l As Integer
l = s.Length
mb.StringValue(length, l) = s
length = length + l
Exception
// If we write of the end of the memoryBlock we need to replace it with a newer // bigger one
TotalLength = TotalLength + bufferSize
mb.Size = TotalLength
mb.StringValue(length, l) = s
length = length + l
Finally, the Action event handler calls getString to assign the appended string to the text property of the Label.
Code Examples
The following example reads a real number into a memory block and then displays it:
Var d As Single
m.SingleValue(0) = 123.456
d = m.SingleValue(0)
MessageBox(d.ToString)
The following example stores a string in a MemoryBlock and displays it:
m.Byte(0) = 12
m.Byte(1) = 72
m.Byte(2) = 101
m.Byte(3) = 108
m.Byte(4) = 108
m.Byte(5) = 111
m.Byte(6) = 32
m.Byte(7) = 87
m.Byte(8) = 111
m.Byte(9) = 114
m.Byte(10) = 108
m.Byte(11) = 100
m.Byte(12) = 33
MessageBox(m.PString(0))
To read the string using CString, add the terminating byte before the call, i.e.,
MessageBox(m.CString(1))
This example backs a BinaryStream with a MemoryBlock that is declared 0-sized:
Var bs As New BinaryStream(mb)
bs.WriteLong(4)
bs.WriteDouble(3.14)
bs.Close
MessageBox(mb.Long(0).ToString)
Note that BinaryStream.Close was called after the write. It is critical that you call Close when you are finished or the size of the MemoryBlock is likely to be wrong.
See Also
BinaryStream class; Declare statement.