Search code examples
c++c++buildervcl

How to check for NULL variant values when vt == VT_NULL does not work?


I am maintaining an old system which uses Borland C++ 2007 and AnsiString values (there's nothing I can do about this, the system is phasing out), and I have this use case :

// declared in the header as class property
AnsiString str;    // { Data:NULL }

// used in a class method
Variant v = str;

if (v.vt == VT_NULL || v.vt == VT_EMPTY)
{
     // do something
}

However v.vt == 256, so the condition is false.

When setting v, do I need to check str.IsEmpty() and set v.vt = VT_NULL manually? Preferably, I'd like a universal method, where str is unknown, and of unknown type; is this too much to ask?

Edit

Is there a way to check if a Variant is of type AnsiString?


Solution

  • However v.vt == 256, so the condition is false.

    256 is varString, which is a custom Variant type specific to Delphi/C++Builder. There is no VARTYPE equivalent of varString in the Win32 VARIANT API, so you can't use a Variant that is holding an AnsiString with Win32 VARIANT functions. You would have to make it hold a BSTR (WideString) instead, which is identified as varOleStr (VT_BSTR).

    When setting v, do I need to check str.IsEmpty() and set v.vt = VT_NULL manually?

    Set it to varNull instead. But yes, if you want the Variant to be a Null type, you have to set it that way explicitly (Variant is initialized as varEmpty by default - yes, there is a difference between Empty and Null).

    You can use the RTL's Variants::Null() function for that purpose, eg:

    #include <Variants.hpp>
    
    AnsiString str;
    
    ...
    
    Variant v;
    if (str.IsEmpty())
        v = Null();
    else
        v = str;
    
    ...
    
    if (VarIsNull(v) || VarIsEmpty(v))
    {
        // do something
    }
    

    Is there a way to check if a Variant is of type AnsiString?

    The vt will be varString, as you have noticed.

    The RTL has a Variants::VarIsStr() function, which checks for both varString (AnsiString) and varOleStr (WideString/BSTR), eg:

    #include <Variants.hpp>
    
    Variant v;
    
    ...
    
    if (VarIsStr(v))
    {
        AnsiString str = v;
        // do something
    }