On Monday, 6 June 2016 at 18:43:33 UTC, ParticlePeter wrote:
On Saturday, 21 May 2016 at 06:36:53 UTC, tsbockman wrote:
...
As an example, if VK_NULL_HANDLE only ever needs to be assigned to opaque types on the D side (that is, types that serve only as an ID or address for communicating with the C side), you could do this:

private struct VkNullHandle { }
enum VK_NULL_HANDLE = VkNullHandle.init;

mixin template VkHandle(bool dispatchable) {
        static if (dispatchable || (size_t.sizeof == 8))
                void* bits = null;
        else
                ulong bits = 0;
        
        this(typeof(this) that) {
                this.bits = that.bits; }
        this(VkNullHandle that) {
                this.bits = typeof(this.bits).init; }

        ref typeof(this) opAssign(typeof(this) that) {
                this.bits = that.bits;
                return this;
        }
        ref typeof(this) opAssign(VkNullHandle that) {
                this.bits = typeof(this.bits).init;
                return this;
        }
}

struct VkDevice { mixin VkHandle!true; }
struct VkInstance { mixin VkHandle!true; }

struct VkFence { mixin VkHandle!false; }
struct VkSemaphore { mixin VkHandle!false; }


void main() {
        VkInstance a = VK_NULL_HANDLE;
        VkFence b = VK_NULL_HANDLE;
}

(DPaste: https://dpaste.dzfl.pl/8f4ce39a907f )

The above is typesafe, and can easily be made compatible with a typical C API, since C does no parameter-related name mangling.

In this case I don't see how it would be possible to use your VkDevice, etc. as argument to the C functions, as they are of different type, no?

They'd be the same type, since you would define the vulkan functions to take these structures instead of pointer or integer types.

It relies on a lot of assumptions about the ABI that make a raw pointer work the same as a structure containing just one pointer, which is why I did not give it much consideration.

Reply via email to