Я пытаюсь использовать новый API vulkan в моей программе C #. Поскольку у нас есть только доступ к заголовочному файлу, я скопировал код и адаптировал его в небезопасный класс, чтобы обернуть его:
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
И на этот раз ошибка из-за массивов фиксированного размера. Любая идея ?
Спасибо за твою помощь !
Задача ещё не решена.
Других решений пока нет …