Empty string becomes null when passed from Delphi to C# as a function argument

c#, com-interop, delphi

Solution

In Delphi, `AnsiString`, `UnicodeString`, and `WideString` values are represented by a `nil` pointer when they are empty. COM uses `BSTR` for strings. Delphi wraps `BSTR` with `WideString`. So there is no way to pass an "empty" non-nil string to a COM method that takes a `WideString` as a parameter, it will be `nil` instead.

Problem

I have a native Delphi exe which calls into C# dll via COM interop. Here's the simplest case which demonstrate this issue: Delphi: ``` IClass1 = interface(IDispatch) ['{B29BAF13-E9E4-33D7-9C92-FE28416C662D}'] function Test(const aStr: WideString): WideString; safecall; end; var obj: IClass1; s: string; begin obj := CoClass1.Create as IClass1; s := obj.Test(''); // Returns '[null]' end; ``` C#: ``` [ComVisible(true)] public interface IClass1 { string Test(string aStr); } [ComVisible(true)] public class Class1 : IClass1 { public string Test(string aStr) { if (aStr == null) return "[null]"; if (aStr == "") return "[empty]"; return "Not empty: " + aStr; } } ``` When I call method Test with an empty string in Delphi, the C# part receives null as a parameter value. Why is that? Shouldn't it be an empty string also?

Original source