Передача массива PVOID, содержащего переменные нескольких типов, в _beginthreadex()

Я хочу передать переменные HANDLE и HWND в функцию _beginthreadex, я не хочу устанавливать эти переменные глобальными.

вот что я пробовал:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 
lpCmdLine, int nShowCmd)
{
    HANDLE t = NULL;
    HWND wnd = NULL;

    // initialization of wnd and t by their functions

   PVOID args[2];
   args[0] = &t;
   args[1] = &wnd;

   _beginthreadex(NULL, 0, threadfunc, args, NULL,NULL,NULL);

   // doing some additional stuff
   return 0;
} 

unsigned int __stdcall threadfunc(PVOID args){
    waitforsingleobject(*(PHANDLE)args[0], INFINITE);
    EnableWindow((PHWND)args[1]) ;
    return 0;
}

это, к сожалению, не работает.. идеи?

1 ответ

Решение

Это не работает, потому что вы не читаете тип args правильно. Вам нужно что-то более похожее на это:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 
lpCmdLine, int nShowCmd)
{
    HANDLE t = NULL;
    HWND wnd = NULL;

    // initialization of wnd and t by their functions

    void* args[2];
    args[0] = &t;
    args[1] = &wnd;

    _beginthreadex(NULL, 0, threadfunc, args, NULL, NULL, NULL);

    // doing some additional stuff
    // make sure args, t and wnd don't go out of scope before the thread terminates...

    return 0;
} 

unsigned int __stdcall threadfunc(PVOID args)
{
    void **pargs = (void**) args;
    HANDLE t = * (HANDLE*) pargs[0];
    HWND wnd = * (HWND*) pargs[1];

    WaitForSingleObject(t, INFINITE);
    EnableWindow(wnd, TRUE);

    return 0;
}

Или, используя динамическое распределение:

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 
lpCmdLine, int nShowCmd)
{
    HANDLE t = NULL;
    HWND wnd = NULL;

    // initialization of wnd and t by their functions

    void **args = new void*[2];
    args[0] = &t;
    args[1] = &wnd;

    if (!_beginthreadex(NULL, 0, threadfunc, args, NULL, NULL, NULL))
        delete[] args;

    // doing some additional stuff
    // make sure t and wnd don't go out of scope before the thread terminates...

    return 0;
} 

unsigned int __stdcall threadfunc(PVOID args)
{
    void **pargs = (void**) args;
    HANDLE t = * (HANDLE*) pargs[0];
    HWND wnd = * (HWND*) pargs[1];

    WaitForSingleObject(t, INFINITE);
    EnableWindow(wnd, TRUE);

    delete[] pargs;
    return 0;
}

Лучшее решение - использовать структуру вместо массива:

struct MyHandles
{
    HANDLE t;
    HWND wnd;
};

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 
lpCmdLine, int nShowCmd)
{
    HANDLE t = NULL;
    HWND wnd = NULL;

    // initialization of wnd and t by their functions

    MyHandles arg;
    arg.t = t;
    arg.wnd = wnd;

    _beginthreadex(NULL, 0, threadfunc, &arg, NULL, NULL, NULL);

    // doing some additional stuff
    // make sure arg doesn't go out of scope before the thread terminates...

    return 0;
} 

unsigned int __stdcall threadfunc(PVOID args)
{
    MyHandles *parg = (MyHandles*) args;

    WaitForSingleObject(parg->t, INFINITE);
    EnableWindow(parg->wnd, TRUE);

    return 0;
}

Или, используя динамическое распределение:

struct MyHandles
{
    HANDLE t;
    HWND wnd;
};

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR 
lpCmdLine, int nShowCmd)
{
    HANDLE t = NULL;
    HWND wnd = NULL;

    // initialization of wnd and t by their functions

    MyHandles *arg = new MyHandles;
    arg->t = t;
    arg->wnd = wnd;

    if (!_beginthreadex(NULL, 0, threadfunc, arg, NULL, NULL, NULL))
        delete arg;

    // doing some additional stuff
    return 0;
} 

unsigned int __stdcall threadfunc(PVOID args)
{
    MyHandles *parg = (MyHandles*) args;

    WaitForSingleObject(parg->t, INFINITE);
    EnableWindow(parg->wnd, TRUE);

    delete parg;
    return 0;
}
Другие вопросы по тегам