如何使用NvAPI_DISP_GetDisplayConfig

How to use NvAPI_DISP_GetDisplayConfig?

本文关键字:DISP GetDisplayConfig NvAPI 何使用      更新时间:2023-10-16

使用 NVAPI 时,我在NvAPI_DISP_GetDisplayConfig时遇到问题。我在第二次调用NvAPI_DISP_GetDisplayConfig时收到AppCrash。似乎想不通为什么。

NvU32 count = 0;
status = NvAPI_DISP_GetDisplayConfig(&count, NULL);
if (status != NVAPI_OK) 
    PrintError(status);
printf("Configs: %in", count);
NV_DISPLAYCONFIG_PATH_INFO *configinfos = new NV_DISPLAYCONFIG_PATH_INFO[count];
configinfos[0].version = NV_DISPLAYCONFIG_PATH_INFO_VER;
status = NvAPI_DISP_GetDisplayConfig(&count, configinfos);
if (status != NVAPI_OK) 
    PrintError(status);

在我的系统上,第一次调用后计数 = 2。关于NvAPI_DISP_GetDisplayConfig的注释说:

NVAPI_INTERFACE NvAPI_DISP_GetDisplayConfig(
__inout NvU32 * 路径信息计数,
__out_ecount_full_opt *路径信息计数 NV_DISPLAYCONFIG_PATH_INFO * 路径信息
)

说明:此 API 允许调用方检索当前全局显示
配置。
用法:调用方可能必须调用三次才能获取所有必需
的内容 配置详细信息如下:
第一次传递:调用方应在设置
路径信息的情况下调用NvAPI_DISP_GetDisplayConfig() 到 NULL 以获取路径信息计数。
第二遍:根据
pathInfoCount(从第一遍)获取//!//!目标信息计数。如果
sourceModeInfo 需要分配内存,或者它可以初始化为 NULL。
第三遍(可选,仅当需要目标信息时才需要):分配
目标信息的内存与
目标信息计数(从第二遍)。支持的操作系统:Windows Vista 及更高

版本

谢谢。

编辑:我也尝试设置configinfos[0].sourceModeInfo = NULL无济于事。我还尝试遍历数组以将所有 .version 和 .sourceModeInfo 设置为无济于事(我在文档中看到的一个例子只在数组中的第一项上设置了版本)

这应该适合您:

NvAPI_Status status = NVAPI_OK;
NvU32 deviceCount = 0;
NV_DISPLAYCONFIG_PATH_INFO_V2 *  pathInfo = NULL;
status = NvAPI_Initialize();
if (status == NVAPI_OK) {
    status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
    if ((status == NVAPI_OK) && (deviceCount > 0)) {
        pathInfo = new NV_DISPLAYCONFIG_PATH_INFO_V2[deviceCount];
        for (int i = 0; i < deviceCount; i++)
        {
            pathInfo[i].targetInfo = 0;
            pathInfo[i].targetInfoCount = 0;
            pathInfo[i].version = NV_DISPLAYCONFIG_PATH_INFO_VER2;
            pathInfo[i].sourceModeInfo = 0;
            pathInfo[i].reserved = 0;
        }
        status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
        if (status == NVAPI_OK) {
            for (int i = 0; i < deviceCount; i++)
            {
                pathInfo[i].sourceModeInfo = new NV_DISPLAYCONFIG_SOURCE_MODE_INFO_V1;
                pathInfo[i].sourceModeInfo->reserved = 0;
                pathInfo[i].targetInfo = new NV_DISPLAYCONFIG_PATH_TARGET_INFO_V2[pathInfo[i].targetInfoCount];
                for (int j = 0; j < pathInfo[i].targetInfoCount; j++) {
                    pathInfo[i].targetInfo[j].details = 0;
                }
            }
        }
        status = NvAPI_DISP_GetDisplayConfig(&deviceCount, pathInfo);
        for (int i = 0; i < deviceCount; i++)
        {
            if (pathInfo[i].sourceModeInfo) delete pathInfo[i].sourceModeInfo;
            if (pathInfo[i].targetInfo) delete [] pathInfo[i].targetInfo;
        }
        delete[] pathInfo;
    }
}

马科斯的回答更彻底。我相信您的代码中的特定问题是您没有初始化第二个路径信息。因此,您需要添加:

configinfos[1].version = NV_DISPLAYCONFIG_PATH_INFO_VER;

这也是一种很好的形式,总是把你的记忆化。因此,在分配后,您应该立即执行以下操作:

memset(configinfos, 0, sizeof(NV_DISPLAYCONFIG_PATH_INFO) * count);

或者您可以单独设置这些值。

NvAPI 附带的示例代码中有一个名为 DisplayConfiguration 的示例,该示例完全利用了 GetDisplayConfig。从 DisplayConfiguration.cpp 复制粘贴函数:

NvAPI_Status AllocateAndGetDisplayConfig(NvU32* pathInfoCount, NV_DISPLAYCONFIG_PATH_INFO** pPathInfo)
{
    NvAPI_Status ret;
    // Retrieve the display path information
    NvU32 pathCount                         = 0;
    NV_DISPLAYCONFIG_PATH_INFO *pathInfo    = NULL;
    ret = NvAPI_DISP_GetDisplayConfig(&pathCount, NULL);
    if (ret != NVAPI_OK)    return ret;
    pathInfo = (NV_DISPLAYCONFIG_PATH_INFO*) malloc(pathCount * sizeof(NV_DISPLAYCONFIG_PATH_INFO));
    if (!pathInfo)
    {
        return NVAPI_OUT_OF_MEMORY;
    }
    memset(pathInfo, 0, pathCount * sizeof(NV_DISPLAYCONFIG_PATH_INFO));
    for (NvU32 i = 0; i < pathCount; i++)
    {
        pathInfo[i].version = NV_DISPLAYCONFIG_PATH_INFO_VER;
    }
    // Retrieve the targetInfo counts
    ret = NvAPI_DISP_GetDisplayConfig(&pathCount, pathInfo);
    if (ret != NVAPI_OK)
    {
        return ret;
    }
    for (NvU32 i = 0; i < pathCount; i++)
    {
        // Allocate the source mode info
        pathInfo[i].sourceModeInfo = (NV_DISPLAYCONFIG_SOURCE_MODE_INFO*) malloc(sizeof(NV_DISPLAYCONFIG_SOURCE_MODE_INFO));
        if (pathInfo[i].sourceModeInfo == NULL)
        {
            return NVAPI_OUT_OF_MEMORY;
        }
        memset(pathInfo[i].sourceModeInfo, 0, sizeof(NV_DISPLAYCONFIG_SOURCE_MODE_INFO));
        // Allocate the target array
        pathInfo[i].targetInfo = (NV_DISPLAYCONFIG_PATH_TARGET_INFO*) malloc(pathInfo[i].targetInfoCount * sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO));
        if (pathInfo[i].targetInfo == NULL)
        {
            return NVAPI_OUT_OF_MEMORY;
        }
        // Allocate the target details
        memset(pathInfo[i].targetInfo, 0, pathInfo[i].targetInfoCount * sizeof(NV_DISPLAYCONFIG_PATH_TARGET_INFO));
        for (NvU32 j = 0 ; j < pathInfo[i].targetInfoCount ; j++)
        {
            pathInfo[i].targetInfo[j].details = (NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO*) malloc(sizeof(NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO));    
            memset(pathInfo[i].targetInfo[j].details, 0, sizeof(NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO));
            pathInfo[i].targetInfo[j].details->version = NV_DISPLAYCONFIG_PATH_ADVANCED_TARGET_INFO_VER;
        }
    }
    // Retrieve the full path info
    ret = NvAPI_DISP_GetDisplayConfig(&pathCount, pathInfo);
    if (ret != NVAPI_OK)    
    {
        return ret;
    }
    *pathInfoCount = pathCount;
    *pPathInfo = pathInfo;
    return NVAPI_OK;
}

现在,此功能可以像以下一样轻松地使用:

NV_DISPLAYCONFIG_PATH_INFO *pathInfo = NULL;
NvU32 pathCount = 0;
_allocateAndGetDisplayConfig(&pathCount, &pathInfo);
// Do whatever you need with the queried display data here
相关文章:
  • 没有找到相关文章