加载从Vulkan Loader库导出的函数

加载从Vulkan Loader库导出的函数
加载(连接)Vulkan Loader库后,为了在我们编写的应用程序中使用Vulkan,需要加载Vulkan Loader库中的函数。但是,不同操作系统使用不同的方式从动态链接库(在Windows中库文件的扩展名为dll,在Linux中库文件的扩展名为so)导出的函数中获取地址。然而,Vulkan力争能够跨多个操作系统运行。因此,为了使开发者不论为哪种操作系统开发应用程序都能够加载Vulkan中的所有函数,Vulkan引入了一个函数,使用该函数可以加载所有Vulkan函数。然而,该函数只能通过操作系统特定的方式加载。
具体处理过程
在Windows操作系统中:
(1)在应用程序的源代码中创建一个PFN_vkGetInstanceProcAddr类型的变量,将其命名为vkGetInstanceProcAddr。
(2)调用GetProcAddress(vulkan_library,”vkGetInstanceProcAddr”)函数,将该操作的结果转换为PFN_vkGetInstanceProcAddr类型,并将之存储在vkGetInstanceProcAddr变量中。
(3)通过查明vkGetInstanceProcAddr变量的值不是nullptr,确认该操作已经成功完成。
在Linux操作系统中:
(1)在应用程序的源代码中创建一个PFN_vkGetInstanceProcAddr类型的变量,将其命名为vkGetInstanceProcAddr。
(2)调用dlsym(vulkan_library,”vkGetInstanceProcAddr”)函数,将该操作的结果转换为PFN_vkGetInstanceProcAddr类型,并将之存储在vkGetInstanceProcAddr变量中。
(3)通过查明vkGetInstanceProcAddr变量的值不是nullptr,确认该操作已经成功完成。
具体运行情况
GetProcAddress()是Windows提供的函数,dlsym()是Linux提供的函数。这两个函数都能够获取已加载的动态链接库中指定函数的地址。需要从Vulkan Loader库中公开导出的唯一函数是vkGetInstanceProcAddr(),使用该函数能够通过独立于具体操作系统的方式,加载任何Vulkan函数。
为了简化和同时自动化加载多个Vulkan函数的工作,并降低出错的可能性,应该将声明、定义和加载函数的代码封装在一组简洁的宏定义中(请参阅前面的内容)。这样通过在宏定义中封装所有Vulkan函数的名称,将这些宏定义存储在一个文件中,我们就能够将所有Vulkan函数都存储在一个文件中。然后,我们可以在多个位置包含这个文件,并利用C/C++的预处理功能。通过重新定义宏,可以重新声明和定义存储函数指针的变量,从而能够加载所有函数。
下面是ListOfVulkanFunctions.inl文件中被修改的部分。
加载从Vulkan Loader库导出的函数

其余文件(VulkanFunctions.h和VulkanFunctions.cpp)没有被修改。这些声明和定义语句会自动被进行预处理的宏执行。然而,仍旧需要加载从Vulkan Loader库导出的函数。下面是本例的实现代码。

加载从Vulkan Loader库导出的函数
加载从Vulkan Loader库导出的函数

反斜杠(\):在C语言中起换行作用,用于宏定义和字符串换行,其中在宏定义中使用居多。如果一行代码有很多元素,导致太长影响阅读,则可以通过在结尾加\的方式,实现换行,编译时会忽略\换行符,当成一行处理。在宏定义中,要换行必须使用\结尾。
上面实现代码中,先定义了一个宏,这个宏负责获取vkGetInstanceProcAddr()函数的地址。该宏通过代表Vulkan Loader库的vulkan_library变量获取vkGetInstanceProcAddr()函数的地址,该宏会将该操作的结果转换为PFN_kGetInstanceProcAddr类型,并将该结果存储到vkGetInstanceProcAddr变量中。然后,这个宏会检查该操作是否成功完成,并在该操作执行失败时,在屏幕上显示适当的消息。

ListOfVulkanFunctions.inl文件被导入后,在该文件中所有为Vulkan函数定义的预处理操作都会完成。本例仅处理了vkGetInstanceProcAddr()函数,使用相同的方式可以处理任何等级的函数。

现在,我们获得了一个用于加载Vulkan函数的函数,这样就可以使用独立于操作系统的方式,获取其他Vulkan函数的指针。

酷客网相关文章:

赞(0)

评论 抢沙发

评论前必须登录!

 

Vulkan实战