March 15, 2017
Is there a safe com variant?

We need to call

To use a variant properly we must

1. CoTaskMemAlloc
2. VariantInit
3. VariantClear
4. CoTaskMemFree

With 1/4 COM calls randomly crash/fail. (which is what lead me to use them)

2/3 are specified by COM spec.

I guess D doesn't have a SafeVariant type. What would be the best way to go about it? Would I need to wrap it in a class?

   class SafeVariant
    {
		VARIANT* v;
		alias v this;
		this()
		{
			v = cast(VARIANT*)CoTaskMemAlloc(VARIANT.sizeof);
			VariantInit(v);
		}

		~this()	            {												 	auto res = VariantClear(v);
			CoTaskMemFree(v);
		}
	}

The main thing above is that it would be nice to alias v this to the struct instead of the ptr of the struct: e.g., alias v* this, which, of course, doesn't work.


So the above is really a SafeVariantPtr, which is only half as useful.




struct VARIANT {
    union {
        struct {
            VARTYPE vt;
            WORD wReserved1;
            WORD wReserved2;
            WORD wReserved3;
            union {
                int lVal;
                LONGLONG llVal;
                ubyte bVal;
                short iVal;
                float fltVal;
                double dblVal;
                VARIANT_BOOL  boolVal;
                SCODE scode;
                CY cyVal;
                DATE date;
                BSTR bstrVal;
                IUnknown punkVal;
                IDispatch pdispVal;
                SAFEARRAY* parray;
                ubyte* pbVal;
                short* piVal;
                int* plVal;
                float* pfltVal;
                double* pdblVal;
                VARIANT_BOOL* pboolVal;
                _VARIANT_BOOL*  pbool;
                SCODE* pscode;
                CY* pcyVal;
                DATE* pdate;
                BSTR* pbstrVal;
                IUnknown* ppunkVal;
                IDispatch* ppdispVal;
                SAFEARRAY** pparray;
                VARIANT* pvarVal;
                void* byref;
                CHAR cVal;
                USHORT uiVal;
                ULONG ulVal;
                ULONGLONG ullVal;
                INT intVal;
                UINT uintVal;
                DECIMAL* pdecVal;
                CHAR*  pcVal;
                USHORT*  puiVal;
                ULONG*  pulVal;
                INT*  pintVal;
                UINT*  puintVal;
                struct {
                    PVOID pvRecord;
                    IRecordInfo pRecInfo;
                }
            }
        }
        DECIMAL decVal;
    }
}