Please why should strings be passed ByVal and not ByRef? The following
works exactly as you'd expect it to:
Public Sub Foo(ByRef s As String)
s = "Foo"
End Sub
Sub Main()
Dim hello As String = "Hello"
System.Console.WriteLine(hello)
Foo(hello)
System.Console.WriteLine(hello)
End Sub
This prints
Hello
Foo
Michi.
I was assuming you were talking about interop... Calling API functions.
In, this case your dealing with pure .NET code, and that is a different
ball of wax

In fact, in that code it won't work byval. This has a lot
to do with the concept of value types vs. reference types and the fact that
reference type variables are actually references (a special kind of
pointer) to an object, and not the actual object.
If you were talking about calling .NET objects from .NET, then yes ByRef is
the way to accomplish what your after. If you calling external API calls,
written in unmanaged Code, then things are a little different because of
the way strings are marshaled. Though, I should have said usually passed
byval, rather then byref - instead of implying that this a 100% situation,
though. In fact, in C# if I wanted to send system.string to a unmanaged
function and have it modified after the call, I would have to pass it as a
ref parameter. The reason for that is that by default reference types
(which string is one of) passed by value are marked with the InAttribute
only - so, you would not see the change made if you passed it by value.
But passing string by reference is not very efficient since there are extra
copies of the string made to make sure that the immutability of
System.String is maintained...
From MSDN:
When a System.String is passed by reference, the marshaler copies the
contents the string to a secondary buffer before making the call. It then
copies the contents of the buffer into a new string on return from the
call. This technique ensures that the immutable managed string remains
unaltered.
In VB.NET things are slightly different with System.String, because it
implements custom marshalling for the string type. For example, in VB.NET
passing the string by value will still result in the changes being visible
to the caller (to maintain some sort of backwards compatibility with
VB.CLASSIC, I would imagine) - but at the expense of even more copying,
which results in further performance degradation and less efficient memory
usage.
You can read up more on default marshalling behavior here:
http://msdn.microsoft.com/library/d...guide/html/cpcondefaultmarshalingbehavior.asp
To make a long story short... In VB.NET and C#, here are some general
rules when passing strings to unmanaged code that will generally result in
the best performance and most efficient use of memory:
1. When calling api calls that take strings, don't alias the function to
the Ansi (or A) version of the the function (this goes for strings in
structures as well). Use the Auto specifier and let the runtime figure out
the appropriate call to make. This will avoid a lot of unnecessary unicode
to ansi conversions on NT based systems.
2. If the string parameter is input only (usually prefixed with an lpsz in
the win32 api), then use system.string byval.
3. If the string is an in/out or out parameter (expected for data to be
returned in the string buffer) then don't use System.String. Use
System.Text.StringBuilder byval. By default stringbuilder byval is given
the inattribute and the outattribute and a pointer to the internal buffer
is passed directly to the unmanaged code. The caveat here is that you are
responsible to make sure that a buffer of the proper capacity is allocated
prior to the call (see, my previous example).
HTH