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

c# convert empty string to null
c# optional parameter string empty
c# function parameter nullable string
c# return a null string
c# parameter string null
how to handle null values in c#
how to pass null value to integer parameter in c#
c# string length null

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?

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.

How Can I Pass Null Or String To Parameter In C# Function , 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? Well, that's just how Delphi represents an empty COM BSTR. If you really need to pass an empty string, you need to change IClass1 in the Delphi code to pass TBStr instead of WideString and use SysAllocString or SysAllocStringLen to create an empty TBStr. Change the declaration of the function in the Delphi code to:

In Delphi, a null (i.e., nil) and empty string are treated as equivalent. As such, passing '' for a string (or WideString) parameter passes nil internally -

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

procedure Foo(const S: WideString);
begin
  WriteLn(Pointer(S) = nil);
end;

begin
  Foo('Something');  //FALSE
  Foo('');  //TRUE
  ReadLn;
end.

The equation of null and empty strings was in fact copied from COM... so a COM library isn't really the place to insist on a C#-style distinction between the two.

Pass NULL value as function parameter?, Empty string becomes null when passed from Delphi to C# as a function argument. 由五迷三道 提交于2019-12-01 11:04:57. I have a native Delphi exe which� In C#, the string is a very special class that is passed by reference In C#, string is a reference type but it is passed by value. You can also use the Alias type String. Other primitive data types are similar, for example, int and Int32, they are all passed by values at default. The following fails to change the value because s is passed by

Why does passing '' to a WideString parameter result in the other side receiving null? Well, that's just how Delphi represents an empty COM BSTR. If you really need to pass an empty string, you need to change IClass1 in the Delphi code to pass TBStr instead of WideString and use SysAllocString or SysAllocStringLen to create an empty TBStr.

Change the declaration of the function in the Delphi code to:

function Test(const aStr: TBStr): WideString; safecall;

And pass SysAllocStringLen('', 0) when you need to pass an empty string.

Here is a complete demonstration:

C#

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication1
{
    [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;
        }
    }

    class Program
    {
        [DllImport(@"Project1.dll")]
        static extern void Foo(IClass1 intf);

        static void Main(string[] args)
        {
            IClass1 intf = new Class1();
            Foo(intf);
        }
    }
}

Delphi

uses
  Ole2;

type
  IClass1 = interface(System.IDispatch)
    function Test(const aStr: TBStr): WideString; safecall;
  end;

var
  EmptyBStr: TBStr;

procedure Foo(const intf: IClass1); stdcall;
begin
  Writeln(intf.Test(nil));
  Writeln(intf.Test(EmptyBStr));
  Writeln(intf.Test(SysAllocString('foo')));
end;

exports
  Foo;

begin
  EmptyBStr := SysAllocStringLen('', 0);
end.

Output

[null]
[empty]
Not empty: foo

Null object, Empty string becomes null when passed from Delphi to C# as a function argument. 由若如初见. 提交于2020-01-21 09:19:12� Calling a method with an out argument. In C# 6 and earlier, you must declare a variable in a separate statement before you pass it as an out argument. The following example declares a variable named number before it is passed to the Int32.TryParse method, which attempts to convert a string to a number.

To avoid errors by null pointers you can send an empty character with Chr (#0) or AnsiChar(#0) instead of '' that returns a null.

Empty string, As I see, your problem is how to built an SQL statement that has complex WHERE clause You SQL - at the end - should look somethng like� Returns Boolean. true if the value parameter is null or Empty, or if value consists exclusively of white-space characters.. Examples. The following example creates a string array, and then passes each element of the array to the IsNullOrWhiteSpace method.

Ssis string null or empty, Hey there! You can pass NULL as a function parameter only if the specific parameter is a pointer. For your example this would work : void myFunc(int a� strings are empty, in C# they are being read as null, and sometimes they are being read as empty strings. This is causing headaches for the C# developers, what in Delphi can I do to *force* the result to always be an EmptyString and not null. Normally, Delphi reads these as empty strings,

SQL: empty string vs NULL value, 25 Component Pascal; 26 D; 27 Delphi; 28 DWScript; 29 Dyalect; 30 D�j� Undefined elements correspond to an empty string; when converted to a Also new in C# 2.0 was the null coalescing operator, '? The value is also used as a default when some function returns fewer pass #obj is seen as null Creating a string via WindowsCreateString with zero characters will produce the handle value NULL. When calling WindowsGetStringRawBuffer with the value NULL, a pointer to an empty string followed only by the NUL terminating character will be returned. No distinct value exists to represent an HSTRING that is uninitialized.

--Returns true if the specified String is white space, empty (''), or null; otherwise, returns Another way to check for an empty string is to use the LEN function. types of type Object is a C# language feature. a string because CHARACTER parameters are passed with a secret See Delphi or Free Pascal� The method will return a Boolean value, like n case if the argument String type has null or empty string (“”), then it will return True value else it will return False value. A Demo Code to Show the Use of Null Method in C#,

Comments
  • Yes, but you are not forced to use WideString, as I point out in my answer.
  • COM does make a distinction. A BSTR can be NULL or a 0-length non-NULL. It is Delphi that does not make a distinction.
  • @RemyLebeau - for sure it can technically be given many COM conventions do not get compiler support in (say) C++. However, code is (or at least was) supposed to treat a null and zero-length BSTR as equivalent (see blogs.msdn.com/b/ericlippert/archive/2003/09/12/52976.aspx)
  • I have updated my question with interface declaration. I didn't add it in the first place, because it was auto generated from the type library.
  • @Max Thanks. My latest update shows you how to pass an empty string.