I've seen some discussions before about people dealing with opaque pointers, or handle types in D.It's a common C practise, and there seems to be uncertainty about the best way to implement this on the D side of the fence.
So I'm looking for opinions... hit me?
I have this in C:
struct Thing;
Thing* MakeThing();
And in D:
struct Thing;
extern (C) Thing* MakeThing();
The question is, does this suck?
D currently can't allocate an array of Thing*'s for some weird reason.
Are there any concerns relating to the GC that I should be aware of when handling pointers returned to me from C code?
So a further goal, and maybe I'll add a little back-story; my 30th birthday game jam from a few weeks back (which is still an active thread!) was interfacing with my engine using basically an extern(C) API precisely mirroring the C headers.
I'm planning on joining another game jam in a couple of week, using D again (maybe I can start another thread as long and controversial as the last one!) ;)
But this time, I want to spend some preparation time building a much more D-styled API to interact with. Again, I'm struggling with just how I should wrap the C calls and opaque types up.
What do people feel is conventional, and has proven to work well?
Again, wrt the opaque pointer problem. I don't really feel using an opaque pointer on the D side is really right.
What I really want to use is something that feels more like a class reference, and I toyed with the idea of abusing class references to hold my handles, and methods would internally case 'this' to my handle type before passing it back into the C code it wraps up.
This seems okay at first, but then you realise there are serious problems with new (wants to return new memory, I can't hook the new operator?), and there's no way to free it automatically, since D is garbage collected rather than ref counted >_<
(Note: I'm still fairly certain that I want a ref-counting GC in D)
So... should I make it a struct with a single void* member?
struct MyThing { void* handle; }
I kinda hate this. the struct keyword totally gives the user the wrong impression, and people have a natural instinct to avoid passing structs around by value, which is exactly how these objects should be handled...
So if I can't present it as a class, and a struct is a pretty shit solution... what?
My objects are opaque handles to engine-managed resources. They are ref-counted, and there is extern(C) API to add/release references to stuff, which I would rather have automated in the D code...
One final problem with ref-counting in D. Since it's not a 1st class feature and requires you to store a ref-count in your object, you can't make your objects immutable anymore because the ref-count needs to be bumped about as the object moves around. Anyone approached this problem?