MemoryBlock

From Xojo Documentation

Class (inherits from Object)

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
LittleEndian Size
Methods
BooleanValue LeftB SingleValue
Byte Long StringValue
CString MidB UInt16Value
ColorValue Operator_Add UInt32Value
CurrencyValue Operator_Compare UInt64Value
DoubleValue Operator_Convert UInt8Value
Int16Value PString UShort
Int32Value Ptr WString
Int64Value RightB
Int8Value Short
Constructors

Constructor(bytes as UInteger)


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

fa-info-circle-32.png
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.

Var s As String = "abcde"
Var mb As MemoryBlock
mb = s
MessageBox(mb.Size.ToString) // displays 5

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.

Var a As String
a = mb

You can also pass this MemoryBlock to a function that expects a String. For example:

MessageBox(mb) // displays "abcde"

OutOfBoundsExceptions with StringValue

Accessing invalid StringValues can raise an OutOfBoundsException. Examples include:

Accessing a MemoryBlock StringValue with a size of 0:

Var mb As New MemoryBlock(0)
Var s As String = mb.StringValue(0, 0) // OutOfBounds because size = 0

Accessing a MemoryBlockStringValue with a size less than 0:

Var mb As New MemoryBlock(0)
Var s As String = mb.StringValue(5, -1) // OutOfBounds because size < 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:

Var m As MemBlockString

// 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:

// This is a class to use a memoryBlock as a temporary buffer
// 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:

Sub AppendString(s As String)
#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.

Sub GetString() As String
#Pragma DisableBackgroundTasks
Return mb.StringValue(0, length)

Code Examples

The following example reads a real number into a memory block and then displays it:

Var m As New MemoryBlock(4)
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:

Var m As New MemoryBlock(13)
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.,

m.Byte(13) = 0
MessageBox(m.CString(1))

This example backs a BinaryStream with a MemoryBlock that is declared 0-sized:

Var mb As New MemoryBlock(0)
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.