Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.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++ 比较外部API中相同类型的两个结构_C++_Struct_C++17_Vulkan_Struct Member Alignment - Fatal编程技术网

C++ 比较外部API中相同类型的两个结构

C++ 比较外部API中相同类型的两个结构,c++,struct,c++17,vulkan,struct-member-alignment,C++,Struct,C++17,Vulkan,Struct Member Alignment,所以基本上,我试图比较Vulkan的两个VkPhysicalDeviceFeatures,一个来自我正在查看的VkPhysicalDevice,另一个对应于我实际需要的一组功能。VkPhysicalDeviceFeaturesstruct仅包含VkBool32成员(属于uint32的typedef),但vulkan的每个次要版本都可以添加未知数量的这些功能。我想做的只是将每个结构的成员相互比较,但不是为了相等,更像是逻辑比较。如果物理设备结构中的对应成员为false,但my struct对该成员

所以基本上,我试图比较Vulkan的两个
VkPhysicalDeviceFeatures
,一个来自我正在查看的
VkPhysicalDevice
,另一个对应于我实际需要的一组功能。
VkPhysicalDeviceFeatures
struct仅包含
VkBool32
成员(属于
uint32的typedef
),但vulkan的每个次要版本都可以添加未知数量的这些功能。我想做的只是将每个结构的成员相互比较,但不是为了相等,更像是逻辑比较。如果物理设备结构中的对应成员为false,但my struct对该成员为true,则比较应返回false

我能想到的唯一方法是发布以下内容:

bool具有所需的功能(VkPhysicalDevice物理设备、,
VKP物理设备(所需功能(U功能){
VkPhysicalDeviceFeatures physical_device_features=getSupportedFeatures(物理_device);
std::size\u t struct\u length=sizeof(VkPhysicalDeviceFeatures)/sizeof(VkBool32);
自动物理设备功能\u bool\u ptr=重新解释播放(&P)物理设备功能;
自动所需的\u功能\u bool\u ptr=重新解释\u强制转换(&所需的\u功能);
对于(std::size\u t i=0;i

这是我想要的(虽然有一种方法可以看出哪个特定成员的名字没有通过比较,但是我认为在反射之外是不可能的)但是我不认为C++能保证这样的严格对齐吗?我有没有跨平台的方法来实现这一点

>你的方法有很大的问题,与C++无关,而且更多的与Vulkan有关。具体而言:

vulkan的次要版本可以添加未知数量的这些结构

这说明您打算将此类技术应用于
VkPhysicalDeviceFeatures2
,以及可能出现在其
pNext
链中的任何功能结构。因此,“这些结构的数量未知”

好吧,事情是这样的:
VkPhysicalDeviceFeatures2
不仅仅是一堆
VkBool
s。它是一个可扩展的Vulkan结构,这意味着它以此类结构常见的
sType
pNext
字段开头。所有1.0版本后的Vulkan设备功能结构也是如此

能够实现您在1.0版后功能结构中所述功能的代码必须能够获取功能结构的整个pNext链并对其进行测试。为了做到这一点,你必须知道它们是什么。无法通过指向任意数据的指针来查询此数据是否包含X个
VkBool
s

要实现这一点,您需要能够将
sType
值映射到该结构的大小。因此,它不能自动扩展(并且,不,C++反射不能修复它;它不能知道什么结构:代码>空隙*Pbx< /Coo>指向);这需要一定程度的手动维护

幸运的是,代码可以清楚地指定特定的
pNext
链中可以存在哪些结构。因此,您可以编写一个工具来加载XML,查找
VkPhysicalDeviceFeatures2
,并处理其
pNext
链中出现的所有结构(这部分说起来容易做起来难,因为XML格式只由Khronos自己的工具处理),以找到可用的结构,并生成你需要的C++信息。我相信,用任何脚本语言编写这样的东西都相对容易

但是由于你已经在(准合理)XML中得到了结构定义,而且你得到了这个工具,它将生成一些C++代码…您只需生成实际的比较逻辑即可。也就是说,不必手工编写成员到成员的比较,只需生成成员到成员的比较。您甚至可以获得不匹配的成员名称

如果要处理任意的
pNext
-链特性,那么需要某种生成器工具。如果你需要一个生成器工具,就用它来解决整个问题

现在,认识到假设的
hasRequiredFeatures
实现的生成代码必须是半复杂的,这一点很重要。如果您允许一个完整的
pNext
结构链,那么您需要构建自己相应的等效结构链,用于从Vulkan进行查询。这可不是什么小事

您需要遍历
pNext
链,并检查每个结构的
sType
字段。但是,当然,
pNext
是一个
void*
,因此您必须稍微撒谎/欺骗C++的规则才能读取
sType
字段。基本上,您必须
void*
重新解释为
VkStructureType*
,读取值,将其与您正在使用的所有可能性进行比较,然后从那里开始。你应该跳过任何你不知道的代码>样式> <代码>,这将需要做更多的C++欺骗。 但您使用的是低级API;打破C++的规则只是你在这里必须习惯的事情

对于每个这样的结构,您需要分配一个匹配的结构,适当地填写其
sType
,然后将其添加到正在构建的
pNext
链中

构建完所有这些之后,就可以进行Vulkan调用、比较、收集数据,最后删除整个结构链


如果您的目标真的是坚持使用VkPhysicalDeviceFeatures而不是可扩展的
bool hasRequiredFeatures(VkPhysicalDevice physical_device,
                              VkPhysicalDeviceFeatures required_features) {

    VkPhysicalDeviceFeatures physical_device_features = getSupportedFeatures(physical_device);
    std::size_t struct_length = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);

    auto physical_device_features_bool_ptr = reinterpret_cast<VkBool32*>(&physical_device_features);
    auto required_features_bool_ptr = reinterpret_cast<VkBool32*>(&required_features);
    for(std::size_t i = 0; i < struct_length; ++i){
        if(physical_device_features_bool_ptr[i] == VK_FALSE && required_features_bool_ptr[i] == VK_TRUE){
            return false;
        }
    }
    return true;
}
bool hasRequiredFeatures(VkPhysicalDevice physical_device,
                              VkPhysicalDeviceFeatures required_features)
{

    constexpr auto feature_count = sizeof(VkPhysicalDeviceFeatures) / sizeof(VkBool32);
    using FeatureArray = std::array<VkBool, feature_count>;

    auto physical_device_features = getSupportedFeatures(physical_device);

    FeatureArray required;
    memcpy(&required, &required_features, sizeof(FeatureArray));

    FeatureArray retrieved;
    memcpy(&retrieved, &physical_device_features, sizeof(FeatureArray));

    bool did_mismatch = false;
    for(auto it_pair = std::mismatch(required.begin(), required.end(), retrieved.begin());
        it_pair.first != required.end();
        it_pair = std::mismatch(it_pair.first, required.end(), it_pair.second))
    {
        did_mismatch = true
        auto mismatch_index = it_pair.first - required.begin();
        //Do something with mismatch_index
    }

    return did_mismatch;
}