Thanks. Ali.
My previous post is not clear that I have to store class reference(object pointer) in void*.

My actual code is try to use libuv in D.

// genarated from uv.h, only two fields is used: 'data', 'type'.
// the document of 'data': "Space for user-defined arbitrary data. libuv does not use this field". // uv_timer_t is the subclass of uv_handle_t in C. (uv_timer_t has all the fields defined in uv_handle_t)
struct uv_handle_t {align(8):
    union {
        struct {void* data; void* _; uv_handle_type type;}
        ubyte[96] _payload;
    }
}
struct uv_timer_t {align(8):
    union {
        struct {void* data; void* _; uv_handle_type type;}
        ubyte[160] _payload;
    }
}
...

// try to resemble the libuv object defined in C.
struct UVHandle {
    uv_handle_t _uvHandle;
    // subclass uv_handle_t
    alias _uvHandle this;

    void close() { // uv_close(&this) }
    bool isClosing() { // uv_is_closing(&this) }
    ...
}

// define Timer as 'final class', in order to force Timer allocated in gc.
final class Timer {
    UVHandle* uvHandle
    // subclass UVHandle
    alias uvHandle this;
    ...

    this()
    {
        // malloc memory(nogc) for uv_timer_t.
        uvHandle = malloc(uv_timer_t.sizeof)

        // store the timer object reference in 'data',
        // but 'alias uvHandle this' also overrides 'cast',
        // this is the problem described as my previous post.
        uvHandle.data = cast(void*) this;
    }
    ~this() { free(uvHandle); }

    void start(...) { // uv_timer_start(this.uvHandle, ...) }
    void stop() { // uv_timer_stop(this.uvHandle) }
    ...
}

My current solution is using 'mixin template' instead of 'alias this' as the way to subclass:

mixin template UVHandle() { ... }
public final class Timer {
    mixin UVHandle;
    ...
}

Reply via email to