class 的 C# 变量在 P/Invoke 调用后归零

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

我正在编写一些 vulkan 代码,运行 解决了一个我无法解决的问题。我有以下代码:

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);
        ...
    }

我遇到的问题是变量 deviceHandle 和 surfaceHandle 在 P/Invoke 调用后重置为 0x0。另外,如果我在调用后声明一个带有某些值的 List 为 null。

我在 MacBook Air dotnet 6 和 MoltenVK 上 运行。有人解释为什么会这样吗?

编辑 1:感谢评论,我发现了问题。这确实是我所说的 stackinbalance,因为传递的结构与 vulkan 预期的内存布局不同。

Vulkan 使用 VkBool32 来表达一个 uint32 布尔值。我有点想,因为一个普通的 bool 也是 4 个字节,所以我可以直接使用它。结果它不知何故不是......当将它更改为 VkBool32 结构(它只有一个 uint32 值)时,它再次按预期工作!

编辑 2:C# 中的 bool 是 1 个字节而不是 4 个字节(就像我怀疑的那样)。

感谢评论,我发现了问题。这确实是我所说的 stackinbalance,因为传递的结构与 vulkan 预期的内存布局不同。

Vulkan 使用 VkBool32 来表达一个 uint32 布尔值。我有点想,因为一个普通的 bool 也是 4 个字节,所以我可以直接使用它。原来它不是......(它在 CLR 上的 1 个字节)当将它更改为 VkBool32 结构(它只有一个 uint32 值)时它再次按预期工作!