Vulkan Cookbook 第一章 5 从Vulkan Loader库加载导出函数

从Vulkan Loader库加载导出函数

译者注:示例代码点击此处

加载(连接)Vulkan Loader库时,我们需要加载它的函数,以便在应用程序中使用Vulkan API。不幸的是,不同的操作系统有不同的方法来获取从动态库导出的函数的地址(Windows上的.dll文件或Linux上的.so文件)。然而Vulkan API在许多操作系统上都是可移植的。因此,为了允许开发人员加载API中可用的所有函数,不管他们针对的是哪个操作系统,Vulkan引入了一个函数,该函数可用于加载所有其他Vulkan API函数。但这个函数本身只能以操作系统的特定方式加载。

怎么做...

在Windows操作系统上:
1.创建一个名为PFN_vkGetInstanceProcAddrvkGetInstanceProcAddr进程变量。
2.调用GetProcAddress(vulkan_library, "vkGetInstanceProcAddr"),将结果强转成PFN_vkGetInstanceProcAddr类型,赋值给vkGetInstanceProcAddr变量。
3.通过检查vkGetInstanceProcAddr变量的值是否不等于nullptr,确认此操作是否成功。

在Liunx操作系统上:
1.创建一个名为PFN_vkGetInstanceProcAddrvkGetInstanceProcAddr进程变量。
2.调用GetProcAddress(vulkan_library, "vkGetInstanceProcAddr"),将结果强转成PFN_vkGetInstanceProcAddr类型,赋值给vkGetInstanceProcAddr变量。
3.通过检查vkGetInstanceProcAddr变量的值是否不等于nullptr,确认此操作是否成功。

这个怎么运作...

Windows系统要用到GetProcAddress()函数。而Liunx系统上用dlsym()函数。它们都从已加载的动态链接库中获取指定函数的地址。必须从Vulkan实现中获取一个导出函数vkGetInstanceProcAddr()。它允许以操作系统无关的方式加载任何其他Vulkan函数。

为了降低拼写错误的概率,我们会将声明、定义和加载函数的过程包装成一组宏定义,如准备加载Vulkan API函数所述,这样可以将所有Vulkan API函数保存在ListOfVulkanFunctions.inl文件中,该文件包含用宏包装的所有Vulkan函数的列表,然后可以在多个地方包含此文件。这样通过重新定义宏,我们可以声明和定义用于存储函数指针的变量。
以下是ListOfVulkanFunctions.inl文件的更新片段:

#ifndef EXPORTED_VULKAN_FUNCTION
#define EXPORTED_VULKAN_FUNCTION( function ) 
#endif

EXPORTED_VULKAN_FUNCTION( vkGetInstanceProcAddr ) 

#undef EXPORTED_VULKAN_FUNCTION

VulkanFunctions.h保持不变。声明和定义是用预处理器宏自动执行的。但是,如前所述我们仍然需要从Vulkan Loader库加载导出的函数。VulkanFunctions.cpp修改部分如下:

#if defined _WIN32
#define LoadFunction GetProcAddress 
#elif defined __linux
#define LoadFunction dlsym
#endif

#define EXPORTED_VULKAN_FUNCTION( name )                         \
name = (PFN_##name)LoadFunction( vulkan_library, #name );        \ 
if( name == nullptr ) {                                          \
  std::cout << "Could not load exported Vulkan function named: " \ 
    #name << std::endl;                                          \ 
  return false;                                                  \
}

#include "ListOfVulkanFunctions.inl"

return true;

首先,我们定义一个宏,它负责获取vkGetInstanceProcAddr()函数的地址,这是从vulkan_library变量表示的库中获取,将该操作的结果转换为PFN_kGetInstanceProcAddr类型,并将其赋值给vkGetInstanceProcAddr变量,之后检查操作是否成功,并在故障的情况下在屏幕上显示适当的消息。

当包含ListOfVulkanFunctions.inl文件并对该文件中定义的每个函数执行前面的操作时,所有预处理器“魔术”就完成了。在这里只是执行vkGetInstanceProcAddr()函数,但对于其他级别的函数实现也是相同的行为。

现在,当我们有一个函数加载函数时,就可以用一个与系统无关的方式来获取指向其他Vulkan函数的指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值