2012-05-24 9 views
1

NVAPI을 사용할 때 NvAPI_DISP_GetDisplayConfig에 문제가 있습니다. NvAPI_DISP_GetDisplayConfig에 대한 두 번째 호출에서 AppCrash가 발생합니다. 이유를 알 수없는 것 같습니다.NvAPI_DISP_GetDisplayConfig를 사용하는 방법?

NvU32 count = 0; 
status = NvAPI_DISP_GetDisplayConfig(&count, NULL); 
if (status != NVAPI_OK) 
    PrintError(status); 
printf("Configs: %i\n", 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 (NvU32 * pathInfoCount __inout
,
을 __out_ecount_full_opt * pathInfoCount NV_DISPLAYCONFIG_PATH_INFO *의 PathInfo
)

설명 :이 API는 호출자가 현재 글로벌 디스플레이를 검색 할 수 있습니다
구성.
사용법 :
첫 번째 패스 :의 PathInfo는
가 pathInfoCount를 가져 NULL로 설정하여 발신자는() NvAPI_DISP_GetDisplayConfig를 호출해야하는 호출자가 다음과 같이 필요한 모든
구성 정보를 가져 오기 위해이 세 번 호출해야 할 수도 있습니다.
두 번째 패스 :
의 번호를 기준으로 pathInfo에 대한 메모리를 할당합니다. // 첫 번째 패스에서 가져온 pathInfoCount! //! targetInfoCount.
sourceModeInfo가 필요한 경우 메모리를 할당하거나 NULL로 초기화 할 수 있습니다.
번째 패스 (선택만을 대상 정보가 필요한 경우 필수) : (두 번째 패스)에서
targetInfoCount 수에 대하여 targetInfo
위한 메모리를 할당한다. 지원 OS : Windows Vista 이상

고마워.

편집 : configinfos [0] .sourceModeInfo = NULL을 사용하지 않으려했습니다. 또한 배열을 반복하여 모든 .version 및 .sourceModeInfo를 사용하지 않도록 설정하려고 시도했습니다 (배열의 첫 번째 항목에 버전 만 설정 한 문서의 예)

답변

2

이 방법이 효과가 있습니다.

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; 
    } 
} 
0

마르코스 답변이 더 철저합니다. 귀하의 코드에서 특정 문제는 당신이 두 번째 pathInfo를 초기화하지 않았다고 믿습니다. 따라서 다음을 추가해야합니다 :

configinfos[1].version = NV_DISPLAYCONFIG_PATH_INFO_VER; 

항상 메모리를 초기화해야합니다. 할당 직후에는 다음을 수행해야합니다.

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

또는 개별적으로 값을 설정할 수 있습니다.

-1

예제 코드에는 DisplayConfiguration이라는 샘플이 있으며 NvAPI와 함께 제공되며 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