VarAdd, VarSub, VarAnd, VarOr functions don't support BYREF VarType

Rene Roessler 0 Zuverlässigkeitspunkte
2024-04-26T21:46:27.5633333+00:00

When I call VarAdd, VarSub, VarAnd, VarOr and similar functions to handle VARIANTs, I have noticed, that indirect VARIANTs are not working.

In your online help you say (i.e. VarAnd)

"...performs a bitwise And operation between two variants of any integral type".

So if (pvarLeft->vt & VT_BYREF) or (pvarRight->vt & VT_BYREF) (i.e. VT_BYREF | VT_I4), pVar->plVal is indeed a pointer to a 4 byte memory block.

HRESULT will throw an error with these Variants.

Why have you stopped here providing the functionality, when you are providing VariantCopyInd, which is supporting VT_BYREF?? It is making a lot of additional code to check for every use of these functions, if there is a VT_BYREF in one of input, and copy the by-refed Variant to a direct Variant and use the function after. Much overhead, ineffective as well.

HRESULT VarAnd(
  [in]  LPVARIANT pvarLeft,
  [in]  LPVARIANT pvarRight,
  [out] LPVARIANT pvarResult
)

Windows
Windows
Eine Familie von Microsoft-Betriebssystemen, die auf PCs, Tablets, Laptops, Smartphones, Internet-of-Things-Geräten, eigenständigen Mixed Reality-Headsets, großen Bildschirmen für die Zusammenarbeit und anderen Geräten ausgeführt werden
26 Fragen
C++
C++
Eine hochentwickelte, allgemeine Programmiersprache, die als Erweiterung der Programmiersprache C entwickelt wurde und neben den Möglichkeiten der Speicherbearbeitung auf untergeordneter Ebene auch objektorientierte, generische und funktionale Features bietet.
14 Fragen
Microsoft Q&A
Microsoft Q&A
Verwenden Sie dieses Tag, um Vorschläge, gewünschte Features und Fehler mit dem Microsoft Q&A-Team zu teilen. Das Microsoft Q&A-Team wertet Ihr Feedback regelmäßig aus und stellt Updates zur Verfügung.
49 Fragen
0 Kommentare Keine Kommentare
{count} Stimmen

1 Antwort

Sortieren nach: Am hilfreichsten
  1. Rene Roessler 0 Zuverlässigkeitspunkte
    2024-04-27T11:26:06.7766667+00:00

    After explaining the problem, you see here my complete solution of adding two variants with VT_BYREF support. You need two more VARIANTS in bad case.

    It would be nice to get a smart solution of MS for Add, Sub etc., i.e. by declaring
    VarAddInd(LPVARIANT, LPVARIANT, LPVARIANT)

    As far as you can see in this code snippet, support for VT_I1, VT_UI2, VT_UI4, VT_UI8 and VT_I8 is missing as well.

    MS has stopped in the middle to support VB6 classic only.

    TCEOLEHELP_DLLEXPORT long __stdcall VariantAdd(LPVARIANT VL, LPVARIANT VR, LPVARIANT VResult) {
        LPVARIANT PL; LPVARIANT PR; long ret;
        if (VarHelpL == NULL) VarHelpL = VariantNew();
        if (VarHelpR == NULL) VarHelpR = VariantNew();
     
        short vt = VL->vt;
        if (vt & VT_BYREF) {
            ret = VariantCopyIndPtr(VarHelpL, VL);
            if (ret) return ret;
            PL = VarHelpL;
            vt = vt & 0x3fff;
        }
        else
            PL = VL;
    
        if (vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4 || vt == VT_UI8 || vt == VT_I8) {
            if (PL == VarHelpL)
                ret = VariantConvertDECIMAL(PL, PL, LOCALE_INVARIANT);
            else {
                ret = VariantConvertDECIMAL(PL, VarHelpL, LOCALE_INVARIANT);
                PL = VarHelpL;
            }
            if (ret) return ret;
        }
    
        vt = VR->vt;
        if (vt & VT_BYREF) {
            ret = VariantCopyIndPtr(VarHelpR, VR);
            if (ret) return ret;
            PR = VarHelpR;
            vt = vt & 0x3fff;
        }
        else
            PR = VR;
    
        if (vt == VT_I1 || vt == VT_UI2 || vt == VT_UI4 || vt == VT_UI8 || vt == VT_I8) {
            if (PR == VarHelpR)
                ret = VariantConvertDECIMAL(PR, PR, LOCALE_INVARIANT);
            else {
                ret = VariantConvertDECIMAL(PR, VarHelpR, LOCALE_INVARIANT);
                PR = VarHelpR;
            }
            if (ret) return ret;
        }
    
        ret = VarAdd(PL, PR, VResult);
        if (PL == VarHelpL) if (VarHelpL) VariantClear(VarHelpL);
        if (PR == VarHelpR) if (VarHelpR) VariantClear(VarHelpR);
        return ret;
    }