Your second example is not functionally identical to the fist example.
The first example is fine. The function takes an open array as an input parameter, and you are constructing a fixed array of strings directly in that parameter, which is perfectly fine. Any array type can be passed to an open array parameter.
In the second example, you are declaring a dynamic array of strings, but you are not allocating any memory for the array, and you are trying to assign its first element (which is a single string) to point at a fixed array of strings. And then you are trying to pass that element (again, a single string) where an array is expected. That is why the code fails to compile.
The correct way to write your procedure would like more like this:
procedure MyProcedure;
var
arr: array of AnsiString;
begin
SetLength(arr, 3);
arr[0] := 'one';
arr[1] := 'two';
arr[2] := 'three';
MyFunction(arr);
end;
Alternatively:
procedure MyProcedure;
var
arr: array of AnsiString;
begin
arr := ['one', 'two', 'three'];
MyFunction(arr);
end;
Alternatively:
type
TAnsiStringArray = array of AnsiString;
procedure MyProcedure;
var
arr: TAnsiStringArray;
begin
arr := TAnsiStringArray.Create('one', 'two', 'three');
MyFunction(arr);
end;