| 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
Permalink
Reply