Search code examples
c#.netpinvokevulkan

C# variables of class are zeroed after P/Invoke call


I'm writing some vulkan code and ran into a problem which I can't get my head around. I've the following code:

NativeMethods.cs:

[DllImport("libvulkan.1.dylib", EntryPoint = "vkGetPhysicalDeviceProperties", CallingConvention = CallingConvention.Cdecl)]
    public static extern void vkGetPhysicalDeviceProperties(IntPtr vkPhysicalDevice, VkPhysicalDeviceProperties* properties);

GraphicsAdapter.cs:

    internal GraphicsAdapter(
        IntPtr deviceHandle,
        IntPtr surfaceHandle)
    {
        VkPhysicalDeviceProperties properties;
        NativeMethods.vkGetPhysicalDeviceProperties(deviceHandle, &properties);
        ...
    }

The Problem that I'm encountering is that the variables deviceHandle & surfaceHandle are reset to 0x0 after the P/Invoke call. Also if I'm declaring a List<string> with some values its null after the call.

I'm running this on a MacBook Air dotnet 6 & MoltenVK. Has anybody an explaination to why this is happening?

Edit 1: Thanks to the comment I found the issue. It was indeed what I would call a stackinbalance because the passed structure had a different memory layout than what was expected by vulkan.

Vulkan uses VkBool32 to express a boolean which is a uint32. I kindof thought since a normal bool is also 4 bytes I can just use it directly. Turns out its somehow not.. When changing it to a VkBool32 struct (which just have a uint32 value) it works again as expected!

Edit 2: A bool in C# is 1 byte not 4 bytes (like I suspected).


Solution

  • Thanks to the comment I found the issue. It was indeed what I would call a stackinbalance because the passed structure had a different memory layout than what was expected by vulkan.

    Vulkan uses VkBool32 to express a boolean which is a uint32. I kindof thought since a normal bool is also 4 bytes I can just use it directly. Turns out its somehow not.. (its 1 byte on CLR) When changing it to a VkBool32 struct (which just have a uint32 value) it works again as expected!