| |
| Posted by Mike Wynn | PermalinkReply |
|
Mike Wynn
| am I right in thinking that there is no way to do anon struct/unions in d ? or has that changed ?
one of the biggest pains with getting the COM headers ported was porting the VARIANT struct;
bit setBrowserPage( IWebBrowser2 webBrowser2, wchar[] url )
{
VARIANT myURL;
VariantInit(&myURL);
myURL.n1.n2.vt = cast(VARTYPE)VT_BSTR;
myURL.n1.n2.n3.bstrVal = SysAllocString(url);
if (!myURL.n1.n2.n3.bstrVal)
{
return false;
}
webBrowser2.Navigate2( &myURL, null, null, null, null);
VariantClear( &myURL );
return true;
}
in c this is just
int setBrowserPage(IWebBrowser2 *webBrowser2, LPTSTR url)
{
VARIANT myURL;
VariantInit(&myURL);
myURL.vt = VT_BSTR;
myURL.bstrVal = SysAllocString(url);
if (!myURL.bstrVal)
{
webBrowser2->lpVtbl->Release(webBrowser2);
return 0;
}
webBrowser2->lpVtbl->Navigate2(webBrowser2, &myURL, 0, 0, 0, 0);
VariantClear(&myURL);
return 1;
}
D makes the use of the COM object easy, but the use of the VARIANT a pain.
I can ofcouse (and am currently doing it) write a wrapper class
so the code becomes
auto MyVariant myURL;
myURL.setAsBSTR( url );
webBrowser2.Navigate2( myURL.asVariantPtr(), null, null, null, null);
but it would be nice to have 2 extra features, (one properties are already
in the D specs, but user defined props are missing)
and the other is wrapper classes for structs.
a wrapper class would be (in java speak) a final base class, it would not be
valid to extend/subclass the wrapper and the "base" class of the wrapper
would be a struct or value
it would require no vtbl, and be automatically passable as iether the
wrapper name or the item it wraps or pointer to wrapped item, and it would
have a constructor that was automatically generated that took the wrapped
item as a param. I known this is all syntactic sugar, but isn't that what
programming langs are anyway?
consider
wrapper class MyVariant : VARIANT {
property( wchar[] str ) bstr
in {
// this is of type VARIANT
releaseOldValue();
n1.n2.vt = cast(VARTYPE)VT_BSTR;
n1.n2.n3.bstrVal = SysAllocString(str);
}
out {
assert( n1.n2.vt == cast(VARTYPE)VT_BSTR );
str = n1.n2.n3.bstrVal;
}
}
effectively
template wrapper( T ) wrappers {
auto class wrapper_class {
T* valPtr;
this() { valPtr = cast(T*)alloca(t.size); }
this( T t ) { valPtr = &t }
this( T * tp ) { valPtr = tp }
T* asPtr() { return valPtr; }
// operator T* {return asPtr(); }
// operator T& {return *asPtr(); }
}
}
although I believe the compiler can inline it all depending on the way its
used
now my code becomes;
MyVariant myURL;
myURL.bstr = url;
webBrowser2.Navigate2( myURL, null, null, null, null);
this would also be great for items like HWND and HDC where full wrapper
classes are not realy required, and just create big vtbls and are never
subclassed.
also I can see this being very useful for wrapping some of the other COM
structs which have arrays with lengths to convert them to/from d array
slices.
|