Unexpected behavior when using both alias this and object pointer
Ali Çehreli via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Thu Jan 12 13:54:21 PST 2017
Hiding a Foo right after Impl can be a solution. However, you need to
pass 't', not '&t' to the C function because
- Although it may be unexpected, cast(void*) is the specified way of
getting the address of a class object
- Taking the address of a class reference (which 't' is one), is just
the address of the reference itself
So, you either have to do something similar to the following or pass
void* to the C function.
import std.stdio: writeln;
import core.stdc.stdlib: malloc;
struct Impl {
ubyte[8] payload;
}
struct ImplWithOwner {
Impl impl;
Foo owner;
}
class Foo {
ImplWithOwner *io;
Impl *payload() {
// Guaranteed by D for structs:
assert(cast(void*)io == cast(void*)&io.impl);
return &io.impl;
}
alias payload this;
this() {
io = cast(ImplWithOwner*) malloc(Impl.sizeof);
io.owner = this;
}
}
static Foo asFoo(Impl* p) {
return (cast(ImplWithOwner*)p).owner;
}
extern(C)
void actual_C_function(Impl* data, void function(Impl*) callback) {
data.payload[0] = 42;
callback(data);
}
extern(C)
void myCallback(Impl* p) {
auto foo = p.asFoo;
assert(foo.io.impl.payload[0] == 42);
}
void main() {
auto t = new Foo();
actual_C_function(t, &myCallback);
}
Ali
More information about the Digitalmars-d-learn
mailing list