www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Safe COM Variant

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;
     }
}
Mar 15 2017