Vulkan 验证层分配如何工作?

问题描述 投票:0回答:1

我已经开始使用 Vulkan,并且刚刚完成了验证层。 在这里,他们将静态函数

static VKAPI_ATTR VkBool32 VKAPI_CALL debugCallback(...)
添加到.cpp文件中,然后简单地赋值

createInfo.pfnUserCallback = debugCallback;

这是如何(/为什么)工作的?我当然知道回调,但我试图将此函数添加到我的渲染器类中,而不仅仅是在 .cpp 文件中的“本地”(?),首先是在头文件中:

VKAPI_ATTR VkBool32 VKAPI_CALL DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* callbackData,
void* pUserData);

然后在.cpp文件中:

VKAPI_ATTR VkBool32 VKAPI_CALL VulkanRenderer::DebugCallback(
VkDebugUtilsMessageSeverityFlagBitsEXT messageSeverity,
VkDebugUtilsMessageTypeFlagsEXT messageType,
const VkDebugUtilsMessengerCallbackDataEXT* callbackData,
void* pUserData)
{
    //...
}

最后像这样使用分配它:

createInfo.pfnUserCallback = &VulkanRenderer::DebugCallback;

我的版本实际上不起作用,所以我可能在这里想错了。但我不知道他们在教程中做了什么,甚至不知道要搜索什么才能理解这一点。

我确实知道要编写什么代码才能使它像他们拥有的那样工作,我只是不知道为什么。

c++ callback vulkan validation-layers
1个回答
0
投票

DebugCallback
为非静态成员函数时,则
&VulkanRenderer::DebugCallback
为成员函数指针。

成员函数指针不是函数指针,但是

pfnUserCallback
想要一个函数指针。

成员函数指针和函数指针不能一样工作,因为非静态成员函数需要知道在哪个对象上调用它,而自由函数则不是这样。

现在,Vulkan 是一个 C API,而不是 C++ API,因此它根本不知道成员函数,并且还使用 C 惯用法来实现回调接口而不是 C++ 接口。

然而,C 惯用语仍然允许传递有关要调用成员函数的对象的信息。这就是

pUserData
的用途。它将原封不动地传递给您的回调,并且回调可以将其用于例如做一个成员函数调用:

createInfo.pUserData = this;
createInfo.pfnUserCallback = [](auto a, auto b, auto c, void* pUserData){ return static_cast<VulkanRenderer*>(pUserData)->DebugCallback(a, b, c); };

(我偷懒了模板参数,你当然可以给它们正确的类型和名称,但编译器也可以推导出它们。)


或者,如果

DebugCallback
不需要是非静态的,你当然也可以将它声明为
static
成员函数。那么你的方法也会奏效。静态成员函数不需要关于调用它的对象的任何附加信息,因此形成像自由函数一样的普通函数指针。

© www.soinside.com 2019 - 2024. All rights reserved.