1

我正在尝试在我的 C# 程序中使用新的 vulkan API。由于我们只能访问头文件,因此我复制了代码并将其调整为一个不安全的类来包装它:

unsafe public static class Vk {
    ...
    public delegate void* PFN_vkAllocationFunction(...);
    public delegate void* PFN_vkReallocationFunction(...);
    public delegate void PFN_vkFreeFunction(...);
    public delegate void PFN_vkInternalAllocationNotification(...);
    public delegate void PFN_vkInternalFreeNotification(...);

    public struct AllocationCallbacks {
        void* pUserData;
        PFN_vkAllocationFunction pfnAllocation;
        PFN_vkReallocationFunction pfnReallocation;
        PFN_vkFreeFunction pfnFree;
        PFN_vkInternalAllocationNotification pfnInternalAllocation;
        PFN_vkInternalFreeNotification pfnInternalFree;
    }
    ...

}

所有的 PFN_xxx 原本都是头部中的函数指针,我直观地把它们改写为委托。所以,目前,它正在工作。但是,在代码的后期,我有以下从 dll 导入的函数,它会出错:

[DllImport("Dll\vulkan-1.dll", EntryPoint = "VkCreateInstance")]
public extern static Result CreateInstance(
    InstanceCreateInfo* pCreateInfo,
    AllocationCallbacks* pAllocator,   <- error here
    Instance* pInstance);

错误是CS0208,由以下消息描述:“无法获取托管类型的地址、大小或声明指向托管类型的指针('Vk.AllocationCallbacks')” 通过谷歌搜索,我了解到 AllocationCallbacks 是管理,因为它的代表。那么我该如何解决这个问题呢?我在网上没有找到令人满意的答案,我试图将我的结构中的委托编组为非托管函数指针(像这样),但它似乎不起作用,编译器保留错误。

public struct AllocationCallbacks {
        void* pUserData;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        PFN_vkAllocationFunction pfnAllocation;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        PFN_vkReallocationFunction pfnReallocation;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        PFN_vkFreeFunction pfnFree;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        PFN_vkInternalAllocationNotification pfnInternalAllocation;
        [MarshalAs(UnmanagedType.FunctionPtr)]
        PFN_vkInternalFreeNotification pfnInternalFree;
    }

这是另一个问题:我有一个结构,其中定义了固定大小的结构数组。原始声明是:

typedef struct VkPhysicalDeviceMemoryProperties {
    uint32_t        memoryTypeCount;
    VkMemoryType    memoryTypes[VK_MAX_MEMORY_TYPES];
    uint32_t        memoryHeapCount;
    VkMemoryHeap    memoryHeaps[VK_MAX_MEMORY_HEAPS];
} VkPhysicalDeviceMemoryProperties;

我只是这样翻译:

[StructLayout(LayoutKind.Sequential)]
public struct PhysicalDeviceMemoryProperties {
    uint memoryTypeCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MEMORY_TYPES)]
    MemoryType[] memoryTypes;
    uint memoryHeapCount;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_MEMORY_HEAPS)]
    MemoryHeap[] memoryHeaps;
}

但同样,我有同样的问题,著名的 CS0208 错误,因为以下函数导入:

[DllImport("Dll\vulkan-1.dll", EntryPoint = "VkGetPhysicalDeviceMemoryProperties")]
public extern static void GetPhysicalDeviceMemoryProperties(
     PhysicalDevice physicalDevice,
     PhysicalDeviceMemoryProperties* pMemoryProperties);   <-error here

而这一次,错误是由于固定大小的数组。任何想法 ?

谢谢你的帮助 !

4

0 回答 0