0

对不起,如果标题不是我的问题所问的。我有点不确定问这个问题的最佳方式。

基本上,我创建了一个 DirectX C++ 应用程序,它当然利用了 Win32 函数。所以我有下面的静态方法

static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);

上面的方法中包含以下 case 语句。

case WM_INPUT:
{
    unsigned __int32 dwSize;
    GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));

    unsigned char *lpb = new unsigned char[dwSize];
    GetRawInputData((HRAWINPUT__*)lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER));

    tagRAWINPUT* raw = (tagRAWINPUT*)lpb;
    InputSystem::handleRawMessage(raw);

    delete[] lpb;
}
break;

好吧,然后方法InputSystem::handleRawMessage(raw); 执行以下操作。

__int32 KEY_STATE[8] = {0, 0, 0, 0, 0, 0, 0, 0};
void InputSystem::handleRawMessage(tagRAWINPUT *raw)
{
    if (raw->header.dwType == RIM_TYPEKEYBOARD) 
    {
        int key = raw->data.keyboard.VKey & 0xFF;
        KEY_STATE[key >> 5] |= 1 << (key & 0x1F);
    }
}

所以我假设 WindowProc 是一个单独的线程,所以我让它访问这些数组并将值存储到它们。好吧,我觉得可能会出现问题,但我不确定这是否安全,因为只有 1 个方法读取和 1 个方法写入。

void InputSystem::handleInput(void)
{
    PREVIOUS_STATE = CURRENT_STATE;
    CURRENT_STATE = 0;
    for (int i = 0; i < MAPPING_SIZE; ++i)
    {
        if (isKeyPressed(MAPPED_KEYS[i]))
        {
            CURRENT_STATE |= 1 << i;
            if (PREVIOUS_STATE & 1 << (0x10 | i))
                CURRENT_STATE |= 1 << (0x10 | i);
        }
    }
    clearKeyStates();
}

bool InputSystem::isKeyPressed(unsigned __int8 key)
{
    return (KEY_STATE[key >> 5] & 1 << (key & 0x1F)) != 0x0;
}

上面的代码“InputSystem::handleInput();” 在为继续绘制 DirectX 图形而启动的 while 循环中调用。

那么上面的代码是否安全执行,或者当两个线程都在相同的值上执行某些事情时我会遇到问题?

我对处理 Win32 的任何事情都很陌生,而且我最近才进入 DirectX,并不是说 DirectX 与此有任何关系。我从来没有真正需要过分担心并发性,所以我从来没有这样做过,但我想了解这种特殊情况以及其他安全和不安全的情况,如果可能的话。谢谢。

while 循环是从下面的代码生成的..

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) 
{
    Dx3DEngine engine = Dx3DEngine(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
    int code = engine.run();
    if (code != 0) 
    {
        engine.createUnsupportedWindow(code);
    }
    return code;
}

int Dx3DEngine::run()
{
    MSG msg;
    msg.message = WM_NULL;
    __int64 cntsPerSec = 0;
    __int64 prevTimeStamp = 0;
    __int64 currTimeStamp = 0;
    QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
    QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);
    const float secsPerCnt = 1.0F / (float)cntsPerSec;
    while(msg.message != WM_QUIT)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        } 
        QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
        float dt = (currTimeStamp - prevTimeStamp)*secsPerCnt;
        update(dt);
        draw();
        prevTimeStamp = currTimeStamp;
    }
    clean();
    return (int)msg.wParam;
}
4

0 回答 0