我正在为 C# 开发一个 Vulkan 包装器(就像我相信很多人一样),我遇到了一些问题,vkGetPhysicalDeviceFeatures
要么不返回数据,要么抛出访问冲突
未管理的一面 - 签名:
规范的签名是这样的:
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 导入:
预期的 DLL 导入(但失败):
[DllImport("vulkan-1.dll", EntryPoint = "vkGetPhysicalDeviceFeatures")]
internal static extern void GetPhysicalDeviceFeatures(PhysicalDeviceHandle physicalDevice, ref IntPtr features);
这类似于其他工作导入。注意:PhysicalDeviceHandle
派生自SafeHandle
应该编组到IntPtr
,我有其他使用这种模式的导入。上面调用时会引发访问冲突。
平台:
- 视窗 10 (x64)
- Nvidia 驱动程序:(
356.43-vkonly
最新)
更新
@V。克拉夫琴科是正确的
上面的导入没有任何问题。我的问题实际上与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
.