vulkan.hpp 扩展的唯一句柄
vulkan.hpp unique handles for extensions
我正在尝试为 vk::DebugUtilsMessengerEXT
对象创建一个唯一句柄。
为此,我将 VkCreateDebugUtilsMessenger()
加载到一个函数指针中,然后调用它来创建纯 C 结构,然后我通过
将其变成一个唯一的 vulkan.hpp 对象
vk::UniqueDebugUtilsMessengerEXT(messenger, instance);
问题由此开始。这种对象隐含地调用析构函数,也就是说它会在变量离开作用域时尝试调用vkDestroyDebugUtilsMessengerEXT
。但是这个函数不能加载到一个同名的指针中。
即定义函数指针为vkDestroyDebugUtilsMessengerEXT
然后设置为
vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT) instance.getProcAddr(
"vkDestroyDebugUtilsMessengerEXT");
当我重新定义符号时会导致编译错误。
error: ‘void (* vkDestroyDebugUtilsMessengerEXT)(VkInstance, VkDebugUtilsMessengerEXT, VkAllocationCallbacks)’ redeclared as different kind of symbol
但是不定义它会导致 linker 错误,因为 linker 无法找到 link 的符号以防止破坏唯一句柄。
/usr/bin/ld: obj/Debug/main.o: in function `vk::DispatchLoaderStatic::vkDestroyDebugUtilsMessengerEXT(VkInstance_T*, VkDebugUtilsMessengerEXT_T*, VkAllocationCallbacks const*) const':
/home/kronos/Desktop/Vulkan/Generated/../libraries/vulkansdk-linux/1.1.97.0/x86_64/include/vulkan/vulkan.hpp:1770: undefined reference to `vkDestroyDebugUtilsMessengerEXT'
我该如何解决这个问题?我如何公开该符号以允许编译?
我找到了解决方案。
定义一个与请求函数同名的函数并调用其中的指针允许编译和链接。
本质上:
void (*vkDestroyDebugUtilsMessenger)(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator);
void vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator)
{
vkDestroyDebugUtilsMessenger(instance, debugMessenger, pAllocator);
}
创建链接和编译所需的符号并:
vkDestroyDebugUtilsMessenger =
(PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
instance, "vkDestroyDebugUtilsMessengerEXT");
将正确初始化指针。
除了上面的答案,还不如像下面的代码:
using unique_debug_utils_messenger_ext = UniqueHandle<DebugUtilsMessengerEXT, DispatchLoaderDynamic>;
...
UniqueInstance instance_{nullptr};
UniqueDevice device_;
unique_debug_utils_messenger_ext debug_messenger_;
DebugUtilsMessengerCreateInfoEXT debug_messenger_create_info;
DispatchLoaderDynamic dispatch_loader_dynamic_;
...
dispatch_loader_dynamic_ = {*instance_, *device_};
debug_messenger_ = instance_->createDebugUtilsMessengerEXTUnique(
debug_messenger_create_info,
nullptr,
dispatch_loader_dynamic_);
该代码使您仍然可以使用智能指针功能。 vulkan.hpp.
中的 DispatchLoaderDynamic 实现中提供了更多详细信息
我正在尝试为 vk::DebugUtilsMessengerEXT
对象创建一个唯一句柄。
为此,我将 VkCreateDebugUtilsMessenger()
加载到一个函数指针中,然后调用它来创建纯 C 结构,然后我通过
vk::UniqueDebugUtilsMessengerEXT(messenger, instance);
问题由此开始。这种对象隐含地调用析构函数,也就是说它会在变量离开作用域时尝试调用vkDestroyDebugUtilsMessengerEXT
。但是这个函数不能加载到一个同名的指针中。
即定义函数指针为vkDestroyDebugUtilsMessengerEXT
然后设置为
vkDestroyDebugUtilsMessengerEXT = (PFN_vkDestroyDebugUtilsMessengerEXT) instance.getProcAddr(
"vkDestroyDebugUtilsMessengerEXT");
当我重新定义符号时会导致编译错误。
error: ‘void (* vkDestroyDebugUtilsMessengerEXT)(VkInstance, VkDebugUtilsMessengerEXT, VkAllocationCallbacks)’ redeclared as different kind of symbol
但是不定义它会导致 linker 错误,因为 linker 无法找到 link 的符号以防止破坏唯一句柄。
/usr/bin/ld: obj/Debug/main.o: in function `vk::DispatchLoaderStatic::vkDestroyDebugUtilsMessengerEXT(VkInstance_T*, VkDebugUtilsMessengerEXT_T*, VkAllocationCallbacks const*) const':
/home/kronos/Desktop/Vulkan/Generated/../libraries/vulkansdk-linux/1.1.97.0/x86_64/include/vulkan/vulkan.hpp:1770: undefined reference to `vkDestroyDebugUtilsMessengerEXT'
我该如何解决这个问题?我如何公开该符号以允许编译?
我找到了解决方案。
定义一个与请求函数同名的函数并调用其中的指针允许编译和链接。
本质上:
void (*vkDestroyDebugUtilsMessenger)(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator);
void vkDestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator)
{
vkDestroyDebugUtilsMessenger(instance, debugMessenger, pAllocator);
}
创建链接和编译所需的符号并:
vkDestroyDebugUtilsMessenger =
(PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(
instance, "vkDestroyDebugUtilsMessengerEXT");
将正确初始化指针。
除了上面的答案,还不如像下面的代码:
using unique_debug_utils_messenger_ext = UniqueHandle<DebugUtilsMessengerEXT, DispatchLoaderDynamic>;
...
UniqueInstance instance_{nullptr};
UniqueDevice device_;
unique_debug_utils_messenger_ext debug_messenger_;
DebugUtilsMessengerCreateInfoEXT debug_messenger_create_info;
DispatchLoaderDynamic dispatch_loader_dynamic_;
...
dispatch_loader_dynamic_ = {*instance_, *device_};
debug_messenger_ = instance_->createDebugUtilsMessengerEXTUnique(
debug_messenger_create_info,
nullptr,
dispatch_loader_dynamic_);
该代码使您仍然可以使用智能指针功能。 vulkan.hpp.
中的 DispatchLoaderDynamic 实现中提供了更多详细信息