我正在尝试初始化Vulkan API。
我遇到的问题是调用vkCreateInstance后收到访问冲突错误,我认为问题来自扩展名和层列表。
我正在使用char buff [20] [256]将它们从字符串传输到API调用的结构,并且在调试器中看到的层和扩展名(3个扩展和15层)都比256短很多字符,并且均以null终止。
扩展名或图层名没有缓冲区溢出,但崩溃了。

我事先使用vkEnumerateInstanceExtensionPropertiesvkEnumerateInstanceLayerProperties接收到的字符串的层和扩展列表,它们都是有效的以空字符结尾的字符串,例如“ VK_KHR_surface”等。

即使它说我支持某些扩展,我是否真的不支持它们,并且在尝试初始化我不支持的扩展时API崩溃,是否有可能?

            void InitializeInstance(void** instance, const vector<string>& layers, const vector<string>& extensions)
    {
        VkApplicationInfo applicationInfo;
            VkInstanceCreateInfo instanceInfo;
            VkInstance* instanceOut = (VkInstance*)instance;

            applicationInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
            applicationInfo.pNext = nullptr;
            applicationInfo.pApplicationName = "MyApp";
            applicationInfo.pEngineName = "MyEngine";
            applicationInfo.engineVersion = 1;
            applicationInfo.apiVersion = VK_API_VERSION_1_0;

            instanceInfo.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
            instanceInfo.pNext = null;
            instanceInfo.flags = 0;
            instanceInfo.pApplicationInfo = &applicationInfo;

            char buffLayer[20][256];
            char buffExt[20][256];

            if(!layers.empty())
            {
                instanceInfo.enabledLayerCount = layers.size();

                for(int i = 0; i < layers.size(); i++)
                {
                    strcpy(buffLayer[i], layers[i].c_str());
                }
                instanceInfo.ppEnabledLayerNames = (char**)buffLayer;
            }
            else
            {
                instanceInfo.enabledLayerCount = 0;
                instanceInfo.ppEnabledLayerNames = nullptr;
            }

            if(!extensions.empty())
            {
                instanceInfo.enabledExtensionCount = extensions.size();

                for(int i = 0; i < extensions.size(); i++)
                {
                    strcpy(buffExt[i], extensions[i].c_str());
                }
                instanceInfo.ppEnabledExtensionNames = (char**)buffExt;
            }
            else
            {
                instanceInfo.enabledExtensionCount = 0;
                instanceInfo.ppEnabledExtensionNames = nullptr;
            }

vkCreateInstance(&instanceInfo, nullptr, instanceOut);
        }


当我只有0个扩展名和0个图层时,它创建成功。如果其中任何一个不为0,则崩溃。

最佳答案

char buffLayer[20][256];
instanceInfo.ppEnabledLayerNames = (char**)buffLayer;


ppEnabledLayerNames应该是一个指向字符数组的指针的数组。但是,您要向其传递2D字符数组,实际上是20 * 256个字符的数组。

如果您使用32位指针的计算机,则驱动程序将获取buffLayer中的前四个字节,并将其视为指向字符数组的指针。但是,您刚刚在其中存储了图层名称的前四个字符,并且'VK_K'可能不会是有效的指针值:)。因此,当尝试取消引用该无效指针时,加载程序将崩溃。

可能最简单的更改是添加:

char* layerNames[20];
for (int i = 0; i < 20; i++)
    layerNames[i] = &buffLayer[i][0];


并将layerNames作为ppEnabledLayerNames传递。

关于c++ - 创建Vulkan实例会导致访问冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49216604/

10-11 00:57