Статический одномерный массив int в качестве значения в карте std::map

Необходимо реализовать блокировку повторных вызовов для DetourAttach относительно загружаемого модуля и индекса функции. Количество индексов заранее известно, а количество модулей не известно.

// индексы функций
const enum
{
    HK_DRAWTEXT,
    HK_DRAWTHEMETEXT,
    HK_DRAWTHEMEBACKGRAUND,
    HK_SETBKCOLOR,
    HK_GETSYSCOLORBRUSH,
    HK_CREATESOLIDBRUSH,
    HK_EXTTEXTOUT,
    HK_CREATECOMPATIBLEDC,
    HK_GETDCEX,
    HK_FILLRECT,
    HK_CLIENTAREA,
    HK_SELECTOBJECT,
    HK_STRETCHBLT,
    HK_DESTROYWINDOW,

    HK_END
};

// карта, в которой ключом является модуль,
// а значением - массив размером по количеству индексов
using  Triple = std::array<int, HK_END>;
std::map<HMODULE, Triple> hookRef{};
typedef std::pair <HMODULE, Triple> In_Pair;

Перед обращением к DetourAttach должно производиться чтение карты и поиск адреса модуля, извлечение соответствующего модулю массива, а затем уже работа с массивом. Запись в карту должна производиться таким образом, чтобы в массиве был счетчик количества обращений по каждому индексу, а в качестве ключа записывался адрес модуля. Как было реализовано у меня без учета модуля с одним массивом:

static int a[HK_END]{};
int(&hookRef)[HK_END] = a;
bool HookIsAttach(int index, PVOID baseAddress, bool attach)
{
    bool hookAttach{ false };
    if ((attach && hookRef[index] == 0) || (!attach && hookRef[index] == 1))
        hookAttach = true;
    hookRef[index] += attach ? 1 : -1;
    return hookAttach;
}

if (HookIsAttach(HK_EXTTEXTOUT, GetModuleHandleW(L"gdi32full.dll"), true))
{
    //DetourAttach...
}

Вот тоже самое, но с привязкой к модулю, чтобы на каждый адрес модуля свой массив был:

std::map<HMODULE, std::array<int, HK_END>> mm{};
typedef std::pair <HMODULE, std::array<int, HK_END>> In_Pair;

bool HookIsAttach(int index, HMODULE baseAddress, bool attach)
{
    bool hookChanged{ false };
    
    std::array<int, HK_END> hookRef;
    auto it = std::find_if(std::begin(mm), std::end(mm),
        [&baseAddress](auto&& p) { return p.first == baseAddress; });

    if (it != std::end(mm))
    {
        hookRef = it->second;
    }
    else
    {
        mm.insert(In_Pair(baseAddress, hookRef));
        //mm[baseAddress] = hookRef;
    }

    if ((attach && hookRef[index] == 0) || (!attach && hookRef[index] == 1))
        hookChanged = true;
    hookRef[index] += attach ? 1 : -1;

    it->second = hookRef;

    return hookChanged;
}

Это вызывает падение на этапе присвоения it->second = hookRef;: Недопустимый параметр был передан функции, для которой недопустимые параметры вызывают неустранимую ошибку. Прошу помощи.


Ответы (1 шт):

Автор решения: Стас Палыч

Сделал следующим образом, работает:

using AttachList = std::unordered_map<PVOID, std::array<int, HK_END>>;
AttachList attListData;
typedef std::pair <PVOID, std::array<int, HK_END>> In_Pair;

bool HookIsAttach(int index, PVOID baseAddress, bool attach)
{
    
    bool hookChanged{ false };
    
    std::array<int, HK_END> &hookRef = attListData[baseAddress];
    
    if ((attach && hookRef[index] == 0) || (!attach && hookRef[index] == 1))
        hookChanged = true;
    hookRef[index] += attach ? 1 : -1;

    //attListData.insert(In_Pair(baseAddress, hookRef));
    
    return hookChanged;
}
→ Ссылка