On Monday, 7 May 2012 at 19:39:04 UTC, Steven Schveighoffer wrote:
I'm just asking if I can call the constructor manually, because
(like I wrote in my first post...) sometimes the C code you're
interoperating with takes control away from you, and just calls a
callback on your behalf when constructing the object.

I wasn't sure, but I just tried it out:

import std.stdio;
extern(C) void *_d_newclass(TypeInfo t);

class C
{
    int x;
    this(int x){this.x = x;}
}

void main()
{
    C c = cast(C)_d_newclass(typeid(C));
    c.__ctor(1);
    writeln(c.x); // outputs 1
}

Seems to work

-Steve


Nonono :( you still missed what I was saying.

Unless you're suggesting I replace _d_newclass, but that isn't type-specific (and I certainly don't want to replace it globally).

Here's another attempt at the explanation:

I definitely CAN make a helper method to do this for me. It's the whole factory pattern, etc.

The problems are that:
(1) The user wouldn't be able to say "new Window()" anymore (I already explained why)
(2) The object couldn't be garbage collected.

Regarding #2, in case it doesn't make sense why:
It's because the C code takes control *AWAY* from you when you tell it to destroy the object. In my case, DestroyWindow(HWND) calls WndProc(WM_DESTROY,..), which is a member function.

I CANNOT call DestroyWindow() in the finalizer, because then WndProc would be called on a *derived* class during cleanup. (It's the *same* issue as with the constructor.) So I'd have to do this manually, which defeats the whole point of making the object garbage-collectible in the first place.


What I'm *want* to be able to do is, basically, to specify that I have a static method that will take care of finalizing an object. (Something like: void finalize(Window o))

Then, when the object is being finalized, the garbage collector would NOT call the object's finalizer directly. Instead, it would call my STATIC method to do the rest of the cleanup.

The STATIC destruction method would call DestroyWindow() on the handle, and DestroyWindow() would send the notification to the window through a modified WndProc() (which I can always redirect, to make it NOT be a member function during the following phase).

It would pass in a context parameter -- which would probably be the Window object itself -- to my (redirected) WndProc. The WndProc() would THEN call the Window's finalizer manually (and tell the GC that the object is done being finalized, so it can be collected).



I can't think of any "nice" way around this. Either the HWND would have to be managed manually (in which case, that defeats the purpose of using the GC to ensure its destruction along with the object), or I would need an extra indirection in Window (which REALLY overcomplicates the design, and introduces lots of inheritance/template usage issues).



The thing is, I think this doesn't need any compiler support either -- just a change in druntime. (I could be wrong though, since it might involve modifying TypeInfo_Class, I'm not sure.)

Do you (or others) reckon a pull request to modify _d_newclass and _d_delclass so that they would call a custom static "constructor" and "destructor" for a class (if it specifies this should be the case) might be accepted?

If there's the possibility then I might try hacking around with it...

I can already see there being issues with inheritance, but I think it would be fixable in some cases, and disallowable in others. (Would obviously need to try it and see though.)

Reply via email to