Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
March 23, 2005 Destructors for structs | ||||
---|---|---|---|---|
| ||||
Is it possible to simulate destructors for structs? I've run into a situation where using a class isn't workable because it has to interop with Win32 COM. struct Variant { static Variant opCall(int value) { Variant var; var.vt = VARTYPE.I4; var.lVal = value; return var; } static Variant opCall(wchar[] value) { Variant var; var.vt = VARTYPE.BSTR; var.bstr = SysAllocString(toUTF16z(value)); return var; } ushort vt; ... int lVal; wchar* bstr; ... } It's basically a wrapper for a COM VARIANT, but instead of having the user do all the tedious initialisation themselves, I want the struct to handle it via opCall. The problem is, of course, without a destructor, I don't get a chance to free the memory allocated from SysAllocString() with SysFreeString(). I've tried implementing it as a class, but it doesn't play well with others (ie, COM functions). |
March 23, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | Probably out of scope: To use variants in variant pool - cyclic buffer. In other words - poor man resource GC struct Variant { static Variant opCall(int value) { poolPos = (poolPos + 1) & 0xFF; FreeVariant(pool[poolPos]); InitVariant(pool[poolPos], .......); return pool[poolPos]; } } Variant[256] pool; uint poolPos; As a rule COM VARIANTs are short living objects used for passing parameters to IDispatch derived objects so this approach will work. Andrew. "John C" <johnch_atms@hotmail.com> wrote in message news:d1s4b0$2n42$1@digitaldaemon.com... > Is it possible to simulate destructors for structs? I've run into a situation where using a class isn't workable because it has to interop with Win32 COM. > > struct Variant { > > static Variant opCall(int value) { > Variant var; > var.vt = VARTYPE.I4; > var.lVal = value; > return var; > } > > static Variant opCall(wchar[] value) { > Variant var; > var.vt = VARTYPE.BSTR; > var.bstr = SysAllocString(toUTF16z(value)); > return var; > } > > ushort vt; > ... > int lVal; > wchar* bstr; > ... > > } > > It's basically a wrapper for a COM VARIANT, but instead of having the user do all the tedious initialisation themselves, I want the struct to handle it via opCall. The problem is, of course, without a destructor, I don't get a chance to free the memory allocated from SysAllocString() with SysFreeString(). > > I've tried implementing it as a class, but it doesn't play well with others (ie, COM functions). > |
March 23, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | John C wrote: > Is it possible to simulate destructors for structs? I've run into a > situation where using a class isn't workable because it has to interop with > Win32 COM. Actually, and please someone correct me quickly if I'm wrong, but I believe D's class/interface system is designed with COM compatability in mind. Check std.windows.iunknown in Phobos, which defines IUnknown for D as a class. -- Chris Sauls |
March 23, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | John C wrote:
> Is it possible to simulate destructors for structs? I've run into a situation where using a class isn't workable because it has to interop with Win32 COM.
>
> struct Variant {
>
> static Variant opCall(int value) {
> Variant var;
> var.vt = VARTYPE.I4;
> var.lVal = value;
> return var;
> }
>
> static Variant opCall(wchar[] value) {
> Variant var;
> var.vt = VARTYPE.BSTR;
> var.bstr = SysAllocString(toUTF16z(value));
> return var;
> }
>
> ushort vt;
> ...
> int lVal;
> wchar* bstr;
> ...
>
> }
>
> It's basically a wrapper for a COM VARIANT, but instead of having the user do all the tedious initialisation themselves, I want the struct to handle it via opCall. The problem is, of course, without a destructor, I don't get a chance to free the memory allocated from SysAllocString() with SysFreeString().
>
> I've tried implementing it as a class, but it doesn't play well with others (ie, COM functions).
>
>
How about a class with an overloaded opCast? (please, don't kill me for this suggestion ;))
_______________________
Carlos Santander Bernal
|
March 23, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Sauls | "Chris Sauls" <ibisbasenji@gmail.com> wrote in message news:d1sc8u$2vi5$2@digitaldaemon.com... > John C wrote: > > Is it possible to simulate destructors for structs? I've run into a situation where using a class isn't workable because it has to > interop with > > Win32 COM. > > Actually, and please someone correct me quickly if I'm wrong, but I believe D's class/interface system is designed with COM compatability in mind. Check std.windows.iunknown in Phobos, which defines IUnknown for D as a class. Yes, D interfaces are compatible with COM interfaces, which is great. But VARIANT isn't a COM interface, it's a plain old struct, and (unlike in C++) D classes aren't compatible with structs because of the vtbl. > > -- Chris Sauls |
March 23, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to Carlos Santander B. | "Carlos Santander B." <csantander619@gmail.com> wrote in message news:d1skpd$79a$1@digitaldaemon.com... > John C wrote: >> Is it possible to simulate destructors for structs? I've run into a situation where using a class isn't workable because it has to interop with Win32 COM. >> >> struct Variant { >> >> static Variant opCall(int value) { >> Variant var; >> var.vt = VARTYPE.I4; >> var.lVal = value; >> return var; >> } >> >> static Variant opCall(wchar[] value) { >> Variant var; >> var.vt = VARTYPE.BSTR; >> var.bstr = SysAllocString(toUTF16z(value)); >> return var; >> } >> >> ushort vt; >> ... >> int lVal; >> wchar* bstr; >> ... >> >> } >> >> It's basically a wrapper for a COM VARIANT, but instead of having the user do all the tedious initialisation themselves, I want the struct to handle it via opCall. The problem is, of course, without a destructor, I don't get a chance to free the memory allocated from SysAllocString() with SysFreeString(). >> >> I've tried implementing it as a class, but it doesn't play well with others (ie, COM functions). > > How about a class with an overloaded opCast? (please, don't kill me for this suggestion ;)) Using opCast() had occurred to me, but I didn't try it until just now. It won't work with inout attributes on parameters -- lvalue hell -- but if I avoid those it's fine. Thanks for the tip! > > _______________________ > Carlos Santander Bernal |
March 24, 2005 Re: Destructors for structs | ||||
---|---|---|---|---|
| ||||
Posted in reply to John C | Struct destructors would be nice, but since we don't have them, you can do it like this: struct->class->data So the struct contains the interface; it can call into the class object, which actually stores the data (or, at least, some of it). The class object won't be GC'd until the struct is also garbage; at that point, you can clean things up with the class destructor. This might be an interesting template. Something like this, perhaps: class Destructor(T) { T val; void delegate(Destructor) destructor; this(void delegate(Destructor) dg) { destructor = dg; } ~this() { destructor(this); } } |
Copyright © 1999-2021 by the D Language Foundation