我正在研究一个用于C#的Vulkan包装器(就像我确定很多人一样)而且我遇到了vkGetPhysicalDeviceFeatures
有点问题,它要么不返回数据,要么抛出Access违反
spec的签名是:
void vkGetPhysicalDeviceFeatures(
VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures* pFeatures);
VkPhysicalDevice
是一个handle
对象,定义为:
#define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
VK_DEFINE_HANDLE(VkPhysicalDevice)
这只是一个指针和其他使用IntPtr
或SafeHandle
包装的导入,用于此形状的对象。
预期的DLL导入(但失败):
[DllImport("vulkan-1.dll", EntryPoint = "vkGetPhysicalDeviceFeatures")]
internal static extern void GetPhysicalDeviceFeatures(PhysicalDeviceHandle physicalDevice, ref IntPtr features);
这与其他工作进口类似。注意:PhysicalDeviceHandle
派生自SafeHandle
应该编组到IntPtr
,我有其他导入这种模式的工作。上面的内容在调用时会引发访问冲突。
356.43-vkonly
(最新)@V。 Kravchenko是correct
上面的导入没有任何问题。我的问题实际上是vkEnumeratePhysicalDevices
来电。
首先我输入错误,正确导入如下:
[DllImport("vulkan-1.dll", EntryPoint = "vkEnumeratePhysicalDevices ")]
internal static extern Result EnumeratePhysicalDevices (InstanceHandle instance, ref physicalDeviceCount, IntPtr[] physicalDevices);
第二关,我实际上错误地使用了这个功能。您需要拨打vkEnumeratePhysicalDevices
两次。第一个调用获取设备数,第二个调用填充设备数组。:
IntPtr[] devices = new IntPtr[]();
uint deviceCount = 0;
// populates deviceCount with the number of devices
Vk.EnumeratePhysicalDevices(instanceHandle, ref deviceCount, null);
// populates the devices array with the handle to each device, will only populate up to deviceCount devices
Vk.EnumeratePhysicalDevices(instanceHandle, ref deviceCount, devices);
注意:这在功能文档的描述/有效使用部分中有概述,我在第一次阅读时没有正确解释。
一旦我从EnumeratePhysicalDevices
获得了正确的句柄值,那么我对GetPhysicalDeviceFeatures
的最终调用就会按预期工作。 GetPhysicalDeviceFeatures
的最终导入如下:
[DllImport("vulkan-1.dll", EntryPoint = "vkGetPhysicalDeviceFeatures")]
internal static extern void GetPhysicalDeviceFeatures(PhysicalDeviceHandle physicalDevice, ref VkPhysicalDeviceFeatures features);
注意:名称中Handle
的任何变量都是SafeHandle
的子类。
答案 0 :(得分:1)
您必须IntPtr
,它实际上指向有效对象,但不仅仅是IntPtr
。访问冲突意味着dll中的代码正在尝试访问内存,而IntPtr
指向并且不能,因为您的IntPtr
未指向有效对象。
总的来说,您应该使用您期望的变体,但将指针传递给有效对象。
工作变体正在工作,因为ref IntPtr
实际上是指向IntPtr的指针,而ref IntPtr
所指向的IntPtr对象的位置是有效的内存。