I'm trying to use the new vulkan API in my C# program. As we only have an access to the header file, I copied the code and I adapted it in an unsafe class to wrap it :
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; } ... } All PFN_xxx was originally function pointers in the header, and I intuitively rewrote them as delegate. So, for the moment, it's working. However, late in the code, I have the following function, imported from the dll, which make an error :
[DllImport("Dll\vulkan-1.dll", EntryPoint = "VkCreateInstance")] public extern static Result CreateInstance( InstanceCreateInfo* pCreateInfo, AllocationCallbacks* pAllocator, <- error here Instance* pInstance); The error is the CS0208, described by the following message : "Cannot take the address of, get the size of, or declare a pointer to a managed type ('Vk.AllocationCallbacks')" By googling a little, I understood that AllocationCallbacks is managed, because of delegates in it. So how can I solve this problem ? I found no satisfying answers on the net, and I tried to marshal delegates in my struct as unmanaged function pointers (like this), but it seems to doesn't work, the compiler keep the error.
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; } Here is another problem : I have a struct in which fixed-size arrays of struct are defined. Original declaration was :
typedef struct VkPhysicalDeviceMemoryProperties { uint32_t memoryTypeCount; VkMemoryType memoryTypes[VK_MAX_MEMORY_TYPES]; uint32_t memoryHeapCount; VkMemoryHeap memoryHeaps[VK_MAX_MEMORY_HEAPS]; } VkPhysicalDeviceMemoryProperties; And I just translated in this way :
[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; } But again, I have the same problem, the famous CS0208 error, because of the following function import :
[DllImport("Dll\vulkan-1.dll", EntryPoint = "VkGetPhysicalDeviceMemoryProperties")] public extern static void GetPhysicalDeviceMemoryProperties( PhysicalDevice physicalDevice, PhysicalDeviceMemoryProperties* pMemoryProperties); <-error here And this time, the error is because of fixed-size arrays. Any idea ?
Thank you for all your help !
delegates are complex C# objects; they cannot be marshalled as simple C/C++ function pointers. Indeed, given that you're using C#, it'd probably be best to just pass NULL for the allocation callbacks. Just let the implementation allocate this stuff.