Question

I have a VB6 window that calls a .NET method, passing inputs from its control's values to the C# code.

I'd like to be able to pass NULL to the C# parameter of (Int32?), but I haven't found anything in my VB6 code that allows me to do so.

Is this possible? If so, what value do I need to pass from VB6 to get NULL in my .NET method?

Was it helpful?

Solution

You can't. In fact, you can't even see the method in your VB6 project. Running Tlbexp.exe on your .NET assembly should always produce a warning that looks similar to this:

TlbExp : warning TX8013117D : Type library exporter warning processing 'IFoo.test(arg), ClassLibrary1'. Warning: Type library exporter encountered a generic type instance in a signature. Generic code may not be exported to COM.

Which was produced by:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface IFoo {
    void test(int? arg);
}

The resulting type library will not have the test() method. It can't be called. The generic type it is complaining about is Nullable<T>, your Int32? is short-hand notation for that.

Long story short, your C# is simply not suitable to be used from a COM client like VB6. You must change the declaration of your argument to object. Test for null first, then cast to (short), the natural fit for VB6. Or use Convert.ToInt32() to be flexible about the value type that the client uses.

OTHER TIPS

Try to pass Nothing to the parameter. It acts as null value.

Not sure what has been changed for the years passed since @HansPassant answer but I was able to use C# nullables in VB6 easily:

C#

[ComVisible(true)]
[Guid(...)]
public class Foo
{
    private int? _arg;

    public int? Arg => _arg;

    public void Test(int? arg)
    {
        _arg = arg;
    }
}

VB6:

Dim foo As New Foo
foo.Test CLng(1234)
Debug.Print foo.Arg '1234
foo.Test Empty
Debug.Print IsEmpty(foo.Arg) 'True
foo.Test CLng(4321)
Debug.Print foo.Arg '4321
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top