Alleine ein VAR anstelle des OUT bringt nicht wirklich eine Veränderung/Lösung.
Jupp, eigentlich würde OUT hier die automatische Speicherverwaltung eines Strings zerschießen,
aber Delphi macht hier heimlich ein VAR aus dem OUT.

Alleine das Erklärt bereits, warum es nichts ändern wird.
Das stimmt nicht. Das kannst du leicht testen:
Delphi-Quellcode:
function StrToBase64(Str: string; var Base64Str: string): Byte;
begin
Base64Str := '';
Base64Str := Str;
end;
procedure Test;
var
a, b: string;
begin
a := 'Test';
StrToBase64(a, a);
ShowMessage(a);
end;
Mit var kommt da "Test" heraus, mit out ein Leerstring.
// EDIT: Wobei ich nicht sicher bin, ob das Verhalten in der Doku genau genug definiert ist, um sich darauf auch bei zukünftigen Delphiversionen zu verlassen. Ich habe nicht nachgeschaut.
Oder ganz zu Beginn Str in eine lokale Variable kopieren,
welche aber lange genug existieren muß, was nicht automatisch sichergestellt ist.
Das bringt nichts, da Delphi den String dort schon abgeräumt hat, also vor dem begin.
Delphi-Quellcode:
S := 1.ToString;
StrToBase64(S, S);
function StrToBase64(Str: string; out Base64Str: string): Byte;
begin
Base64Str := '';
ShowMessage(Str); // hier kommt '1' raus
Delphi-Quellcode:
S := 1.ToString;
S2 := S;
StrToBase64(S, S);
function StrToBase64({const} Str: string; out Base64Str: string): Byte;
begin
Base64Str := '';
ShowMessage(Str); // hier kommt '1' raus, egal ob mit oder ohne const
(hab das jetzt nicht getestet, aber rein logisch müsste es passen)
Du solltest es testen. Es stimmt leider nicht.
Den Vergleich hatte ich auch ausprobiert. Da darf nur nicht geprüft werden, ob
Str <> ''
ist wie in deinem Code, sondern nur der Pointer verglichen werden.