From the docs MemoryBlocks are objects so, as a general rule, they are supposed to be passed by reference to functions.
In effect they are passed to functions by value i.e. a function gets a copy of the Memoryblock.
They are passed as a reference (not ByRef, that’s a different thing). If you modify the contents of the memoryblock, the calling routine will see your changes. Unless, of course, you pass a memoryblock to a parameter declared as string, in which case the memoryblock will auto-convert to a string and you get a copy of the contents.
What are you seeing that makes you think you’re getting a copy?
ByRef is used for scalar values (mostly). And in some cases with Declares.
This is a method with a regular scalar parameter:
Sub SomeSub(i As Integer)
...
End
The parameter i is like a local variable:
Sub SomeSub()
Dim i As Integer = the value handed of as argument by the calling method
...
End
With ByRef you don’t get a local copy. If you change the value of i within SomeSub, it will change the value in the calling method:
Ok, after doing some tests with a user defined class now I must admit my totally wrong knowledge when speaking of “objects are passed by reference”.
At this point also the conversation title is misleading.
I try to explain my observation at my best.
Sub MyFunction(srcblk As MemoryBlock)
srcblk = new MemoryBlock(1024)
End Sub
Looking at the above function, I was thinking that this code was able to return a new chunk of memory but this is not the case.
In effect the code create a new MemoryBlock valid only for the function itself completely different from the one used by the caller.
To return a new MemoryBlock to the caller you must declare the parameter with ByRef.
The final result is that when you pass an object to a function you get a copy of the reference to the object not the reference to the object itself.
Using the C language syntax the function gets “object *” and not “object **”.
So mixing my knowledge of the C language with some english word misinterpretation created this “ancestral” (to me) invalid knowledge of ByRef and “objects passed by reference”.
The reference to an object the pointer is a scalar value and passed ByVal I think. I such a case you need to use ByRef.
But I would never do it that way, because you have an uninitialized variable lingering around. And with MemoryBlocks this is very dangerous. I would initialize the MemoryBlock in the caller method immediately. If you don’t know how many bytes you have to reserve in memory, create two functions, one that calculates how many bytes are needed and a second one to which you hand over the initialized MemoryBlock. So you would have this:
Dim srcblk As New MemoryBlock(HowManyBytesToAllocateFunction())
MyFunction(srcblk)
Or you combine both things into one function:
Function MyFunction(Optional srcblk As MemoryBlock = Nil) As Integer
If srcblk = Nil Then
Return 1024
Else
srcblk.StringValue(0, ... // set the value here
End
End
The call would then look like this:
Dim srcblk As New MemoryBlock(MyFunction())
Call MyFunction(srcblk) // Call keyword is needed here so the compiler doesn't insist on assigning the return value