You can use something like this to transfer strings and interfaces (unfortunately its not possible to pass an array of custom records, you will need to create an interface that will act as array or list to do so):
uses
VarUtils;
type
TWideStringArray = array of WideString;
TDispatchArray = array of IDispatch;
function SafeArrayAsDispatchArray(ar: PVarArray): TDispatchArray;
var
lb, ub, i: Integer;
ind: array [0…0] of Integer;
begin
SafeArrayGetLBound(ar, 1, lb);
SafeArrayGetUBound(ar, 1, ub);
SetLength(result, ub-lb+1);
for i := lb to ub do begin
ind[0] := i;
SafeArrayGetElement(ar, @ind, @result[i-lb]);
end;
end;
function DispatchArrayAsSafeArray(Arr: TDispatchArray): PVarArray;
var
Bounds: TVarArrayBoundArray;
I: Integer;
ind: array [0…0] of Integer;
begin
Result := nil;
if (Arr = nil) or (Length(Arr) = 0) then
Exit;
Bounds[0].LowBound:=0;
Bounds[0].ElementCount:=Length(Arr);
Result := SafeArrayCreate(varDispatch, 1, Bounds);
for I := 0 to Length(Arr) - 1 do begin
ind[0] := i;
SafeArrayPutElement(Result, @ind, PDispatch(Arr[i]));
end;
end;
function SafeArrayAsStringArray(ar: PVarArray): TWideStringArray;
var
lb, ub, i: Integer;
ind: array [0…0] of Integer;
begin
SafeArrayGetLBound(ar, 1, lb);
SafeArrayGetUBound(ar, 1, ub);
SetLength(result, ub-lb+1);
for i := lb to ub do begin
ind[0] := i;
SafeArrayGetElement(ar, @ind, @result[i-lb]);
end;
end;
function StringArrayAsSafeArray(Arr: TWideStringArray): PVarArray;
var
Bounds: TVarArrayBoundArray;
I: Integer;
ind: array [0…0] of Integer;
begin
Result := nil;
if (Arr = nil) or (Length(Arr) = 0) then
Exit;
Bounds[0].LowBound:=0;
Bounds[0].ElementCount:=Length(Arr);
Result := SafeArrayCreate(varOleStr, 1, Bounds);
for I := 0 to Length(Arr) - 1 do begin
ind[0] := i;
SafeArrayPutElement(Result, @ind, PWideChar(Arr[i]));
end;
end;