1

NVAPI を使用している場合、NvAPI_DISP_GetDisplayConfigに問題があります。NvAPI_DISP_GetDisplayConfig への 2 回目の呼び出しで AppCrash が発生します。理由がわからないようです。

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);

私のシステムでは、最初の呼び出しの後、count = 2 です。NvAPI_DISP_GetDisplayConfig に関するメモには、次のように記載されています。

NVAPI_INTERFACE NvAPI_DISP_GetDisplayConfig(
__inout NvU32 * pathInfoCount,
__out_ecount_full_opt *pathInfoCount NV_DISPLAYCONFIG_PATH_INFO * pathInfo
)

説明: この API を使用すると、呼び出し元は現在のグローバル ディスプレイ
構成を取得できます。 使用法:呼び出し
元は、必要なすべての
構成の詳細を取得するために、次のようにこれを 3 回呼び出す必要がある場合があります 。 2 番目のパス: pathInfoCount (最初のパスから) の数に関して、pathInfo にメモリを割り当て て取得します //! //! targetInfoCount. sourceModeInfo が必要な場合は、メモリを割り当てるか、NULL に初期化することができます。 3 番目のパス (オプション、ターゲット情報が必要な場合にのみ必要): の数に関して targetInfo にメモリを割り当てます。







targetInfoCount (2 番目のパスから)。対応OS:Windows Vista以降

ありがとう。

編集: configinfos[0].sourceModeInfo = NULL を無駄に設定しようとしました。また、配列を反復処理して、すべての .version および .sourceModeInfo を無駄に設定しようとしました (配列の最初の項目にのみバージョンを設定したドキュメントの例)

4

3 に答える 3

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;
    }
}
于 2012-08-17T20:12:58.453 に答える
0

マルコスの答えはもっと徹底的です。コードの特定の問題は、2番目のpathInfoを初期化していないことだと思います。したがって、次を追加する必要があります。

configinfos[1].version = NV_DISPLAYCONFIG_PATH_INFO_VER;

常にあなたの記憶を初期化することも良い形です。したがって、割り当ての直後に次のことを行う必要があります。

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

または、値を個別に設定できます。

于 2012-10-02T19:03:17.023 に答える
-1

GetDisplayConfig を完全に悪用する NvAPI に付属するサンプル コードに、DisplayConfiguration という名前のサンプルがあります。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
于 2014-08-14T07:22:18.083 に答える