It is very dangerous to pass pointers to managed datastructures like strings or arrays, because when dereferencing you might still trigger the lazy copy mechanisms:
procedure Foo(p: PString);
begin
// This triggers lazy copy
p^[1] := 'A';
end;
var
s1, s2: String;
begin
ReadLn(s1);
s2 := s1;
Foo(@s2);
WriteLn(IntPtr(s1));
WriteLn(IntPtr(s2));
end.
If Foo would be now from a library, this would trigger a new allocation of the memory that s2 points to within the library, even though it is "owned" by s2, which is not located in the library.
That said, as already stated by MarkMLI above, you can use cmem, this uses the c memory manager, which comes from the libc and therefore from a library, and thereby causes both the main program and the library to use the same memory manager, and therefore have the same heap.
That said, I think as soon as you use heaptrc (as in the example from MarkMLI), this doesn't work anymore. So you can cross manage heap memory with cmem, but not with cmem and heaptrc.
Also, needless to say, the internal representation of the strings or arrays may also vary between compiler versions, so passing strings or arrays, as pointer or directly may only work with the same compiler version.
Lastly, to be perfectly safe, the best way to pass strings and arrays do this is to simply pass them as element pointers and length:
procedure UseLibraryString(strData: PChar; strLength: SizeInt);
var
str: String;
begin
SetLength(str, strLength);
Move(strData^, str[1], strLength);
// Use str
end;
procedure UseLibraryArray(arrData: PInteger; arrLength: SizeInt);
var
i: Integer;
begin
for i:=0 to arrLength -1 do
WriteLn(arrData[i]);
end;