On Monday, 27 July 2015 at 12:03:06 UTC, Vlad Leberstein wrote:
Hi! My use case requires interaction with C API which in turn implies storing object instance reference as void *. I'm using gdc 4.9.2 and everything worked fine with "object -> void * -> object" conversion, but "object -> void * -> interface" failed. The stripped-down example is something like this:

interface TestInterface {
    void testMethod();
}

class TestImpl : TestInterface {
    void testMethod() {
        writefln("TestImpl::testMethod\n");
    }
};

void testDispathcer(void *rawSelf) {
    auto self = cast(TestInterface) rawSelf;
    // nothing happens
    self.testMethod();
}


int main(string[] args) {
    auto t = new TestImpl();
    testDispathcer(cast(void *) t);
    return 0;
}

However this works:

void testDispathcer(TestImpl rawSelf) {
    auto self = cast(TestInterface) rawSelf;
    // TestImpl::testMethod is printed to stdout
    self.testMethod();
}


int main(string[] args) {
    auto t = new TestImpl();
    testDispathcer(t);
    return 0;
}

Is there any way to handle such situation without resorting to templating dispatcher with every *Impl type? As second example works as expected I presume that runtime loses some type information to perform downcast and maybe it's possible to extract it and store externally and merge back later?

I'm quite new to D and sorry if the question is dumb. Any help would be greatly appreciated! Thanks in advance!

In the first example, you pass a pointer to a class instance. You cannot get the vtbl entry for the interface like this. Instead try to do this in 2 steps:

---
import std.stdio;

interface TestInterface {
    void testMethod();
}

class TestImpl : TestInterface {
    void testMethod() {
        writefln("TestImpl::testMethod\n");
    }
};

void testDispathcer(void *rawSelf) {
    auto obj = cast(Object) rawSelf;
    auto self = cast(TestInterface) obj;
    // nothing happens
    self.testMethod();
}


int main(string[] args) {
    auto t = new TestImpl();
    testDispathcer(cast(void *) t);
    return 0;
}
---

Reply via email to