Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用设置计数和填充数组的函数?_C++_Arrays_Vulkan - Fatal编程技术网

C++ 如何使用设置计数和填充数组的函数?

C++ 如何使用设置计数和填充数组的函数?,c++,arrays,vulkan,C++,Arrays,Vulkan,Vulkan API函数包含计数地址和数组地址作为参数。对于这个问题,可以忽略第一个参数。功能签名如下: VkResult vkEnumerateInstanceExtensionProperties( const char* pLayerName, uint32_t* pPropertyCount, VkExtensionPropertie

Vulkan API函数包含计数地址和数组地址作为参数。对于这个问题,可以忽略第一个参数。功能签名如下:

VkResult vkEnumerateInstanceExtensionProperties(
    const char*                                 pLayerName,
    uint32_t*                                   pPropertyCount,
    VkExtensionProperties*                      pProperties);
vkEnumerateInstanceExtensionProperties的行为,如文档所定义(如上链接):

如果
pProperties
参数为
nullptr
,则
pPropertyCount
参数设置为可用结构的数量

否则,
pPropertyCount
应反映传递的
pProperties
数组的大小,并填充该数组。如果数组太小,则返回第一个
pPropertyCount
项(函数返回错误代码)

我想这是一个在C++中有点常见的设计选择(或者至少在VulkAN API中),否则我在Vulkan的最初几小时就不会碰到它,所以我的问题(下面我问)可能更一般地回答,但是Vulkan特有的答案也很受欢迎。
我想检索这个函数提供的所有结构

I was(松散地)following指定我应该使用以下“算法”来实现这一点:

  • 通过第一次调用检索元素计数
  • 分配一些数组或数据结构
  • 用第二次调用填充数组
  • 在类似这样的代码中(本教程使用向量并传递其保留数组):

    但是,这需要调用Vulkan API函数两次。我觉得这不是Vulkan API设计者的意图。有没有更好的方法来检索结构列表

    声明如果API状态更改,则连续调用之间可用结构的数量可能会有所不同

    我想这是C语言中比较常见的设计选择++

    我想这是一个普通的[API ]设计选择,在C++中有其他更好的方法来完成这一任务(也许返回一个<代码>:ST::vector < /代码>这里是合适的)。 但是,这需要调用Vulkan API函数两次。我觉得这不是Vulkan API设计者的意图


    在我看来,这正是我的意图,否则教程不会这么说!否则你会怎么做?无论如何,我不会太担心的。如果那样做很昂贵,他们就不会那样做

    Vulkan文档页面指出,如果API状态发生变化,则连续调用之间可用结构的数量可能会有所不同

    这听起来不太可能在实践中发生,只需浏览一下该链接,但如果您得到
    VK_complete
    返回,您可以扔掉结果,重新开始

    在代码中看起来像这样

    这看起来很好——在C -但是C++中,教程正在做什么(使用向量并通过它的保留数组)将是我的选择。我想,VulcAN API是故意用C编写的,所以C和C++程序都可以利用它。


    编辑,以解决OP在评论中关于Vulkan为什么选择这种API风格的问题:

    嗯,这很实用。抛开我发现的一个非常不相关的细节,关于它应该是一个函数还是两个函数(谁在乎,真的?),更好的问题是谁应该分配必要的内存来保存结果以及为什么

    有两种基本方法:

  • 调用者分配所需的内存,然后负责在完成时释放内存
  • 该库分配所需的内存,并提供一个附加的(可能是通用的)函数,以便在调用者使用完内存后释放它
  • 方法1在Win32 API中广泛使用,它的优点是您从教程中引用的示例,即(为简洁起见,省略了错误检查):

    uint32\u t extensionCount=0;
    vkEnumerateInstanceExtensionProperties(nullptr和extensionCount、nullptr);
    std::向量扩展(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr,&extensionCount,extensions.data());
    
    这是可能的。如果库分配内存,这就更麻烦了

    方法2意味着您只需要调用
    vkEnumerateInstanceExtensionProperties()
    一次,因为它可以分配所需的内存量并返回给您

    因此,方法1更灵活,方法2当然更方便,也许更高效(效率有多高完全取决于API背后的内容)

    请注意:让库分配内存并让调用方释放内存不是一个明智的选择。这样做是走向毁灭的道路(他们可能使用不同的堆,例如,想象一下会造成的混乱)

    <强>建议:将你打算使用的Vulkan的一部分包裹在一个友好、友好的C++ API后面,这样在最合适的容器中返回这样的结果。如果你打算认真使用它,你会很高兴你做的。


    更新:哦,已经有人这么做了,请看上面@Ekzuzy的评论。很好。

    @Jochem只是一个提醒-擦亮我的答案,你可能想再看一眼。谢谢,这正是我想要的答案!你知道C风格API设计使用此模式的原因吗?对我来说,似乎违反了规则单一责任原则;该函数既涉及数据的传递,也涉及数据的计数。至少,一个
    *-Count
    (后缀)函数的唯一目的是报告元素的数量。@jochemkuippers我认为这种设计选择是为了减少(不必要的)元素的数量API公开的函数。至于责任-获取所需的内存是开发人员的责任
    uint32_t count = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr); // only retrieve count
    VkExtensionProperties* list = new VkExtensionProperties[count];
    vkEnumerateInstanceExtensionProperties(nullptr, &count, list); // now populate the array
    // after use
    delete[] list;
    
    uint32_t extensionCount = 0;
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, nullptr);
    std::vector<VkExtensionProperties> extensions(extensionCount);
    vkEnumerateInstanceExtensionProperties(nullptr, &extensionCount, extensions.data());