I have a C# application which calls native Delphi dll using the following code:
C#
[DllImport(\"NativeDLL.dll\", CharSet = CharSet.U
You cannot pass a string from native managed that way. Your code is wrong in 32 bit also, you just happen to get away with it. The second version of the code is also wrong. It only appears to work.
You need to either:
Option 2 is always preferable. It looks like this:
[DllImport("NativeDLL.dll", CharSet = CharSet.Unicode)]
public static extern int GetString(StringBuilder str, int len);
On the native side you would have
function GetString(str: PChar; len: Integer): Integer; stdcall;
begin
StrLCopy(str, 'abc', len);
Result := 1; // real code would have real error handling
end;
Then call this like so:
StringBuilder str = new StringBuilder(256);
int retval = GetString(str, str.Capacity);
If you want to try option 1, it looks like this on the managed side:
[DllImport("NativeDLL.dll", CharSet = CharSet.Unicode)]
public static extern int GetString(out string str);
and like this native:
function GetString(out str: PChar): Integer; stdcall;
begin
str = CoTaskMemAlloc(SizeOf(Char)*(Length('abc')+1));
StrCopy(str, 'abc');
Result := 1; // real code would have real error handling
end;
When the managed code copies the contents of str
to the string value, it then calls CoTaskMemFree
on the pointer that you returned.
And this is trivially easy to call:
string str;
int retval = GetString(out str);