我正在为 C# 开发 Vulkan 包装器(我相信很多人都是这样),我在使用 vkGetPhysicalDeviceFeatures
时遇到了一些问题,它要么不返回数据,或抛出访问冲突
未管理方 - 签名:
来自 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 导入:
预期的 DLL 导入(但失败):
[DllImport("vulkan-1.dll", EntryPoint = "vkGetPhysicalDeviceFeatures")]
internal static extern void GetPhysicalDeviceFeatures(PhysicalDeviceHandle physicalDevice, ref IntPtr features);
这类似于其他工作导入。注意:PhysicalDeviceHandle
派生自 SafeHandle
应该编码为 IntPtr
,我有其他导入的此模式有效。以上在调用时引发访问冲突。
平台:
- Windows 10 (x64)
- Nvidia 驱动程序:
356.43-vkonly
(最新)
更新
@V。克拉夫琴科是 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
的子类.
最佳答案
您必须 IntPtr
,它实际上确实指向一个有效对象,而不仅仅是 IntPtr
。访问冲突意味着 dll 中的代码正在尝试访问内存,您的 IntPtr
指向但不能,因为您的 IntPtr
未指向有效对象。
总的来说,您应该使用您期望的变体,但将指针传递给一个有效的对象。
工作变体正在工作,因为 ref IntPtr
实际上是指向 IntPtr 的指针,而 ref IntPtr
指向的 IntPtr 对象的位置是有效内存。
关于c# - P/调用 vkGetPhysicalDeviceFeatures 访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35594281/