CreateThread, передающий long в lpParameter

#c #visual-c -2010

#c #visual-c -2010

Вопрос:

Компилятор сообщает о «недопустимой косвенности» в строке 3. В IDE указано, что «выражение должно быть указателем на полный тип объекта»

 001 DWORD WINAPI MyCallbackFunction( LPVOID lpvParam )
002 {
003    long value = (long) *lpvParam;
004    ...
005    return 0;
006 }
007
008 BOOL StartMyThread( long value )
009 {
010    DWORD dwThreadId;
011    BOOL result = FALSE;
012    HANDLE hThread = NULL;
013    hThread = CreateThread(NULL, 0, MyCallbackFunction, amp;value, NULL, amp;dwThreadId );
014    result = (NULL == hThread);
015    CloseHandle( hThread );
016    return resu<
017 }
  

Если я изменю строку 3 на эту, она компилируется, но завершается сбоем…

 long value = (long) lpvParam;
  

Комментарии:

1. Я забыл снять звездочку. Я исправил это.

Ответ №1:

Вы пытаетесь отразить void* указатель, что недопустимо. Сначала вы должны привести его к другому типу указателя. Поскольку ваш параметр является указателем на long , вам нужно сделать это вместо:

 long *value = (long*) lpvParam;
  

Или, если потоку не нужен доступ к исходной переменной:

 long value = * (long*) lpvParam;
  

Однако Сет прав. Исходная переменная исчезнет к тому времени, когда поток действительно начнет выполняться. Если вы пытаетесь передать его значение потоку, сделайте это вместо:

 // notice the 'amp;' operator is gone now...
hThread = CreateThread(NULL, 0, MyCallbackFunction, (LPVOID)value, NULL, amp;dwThreadId );
...    
long value = (long) lpvParam;
  

Ответ №2:

Вы даете указатель на локальную переменную, которая может быть уничтожена типом, выполняемым потоком. Было бы лучше привести long к LPVOID в вызове CreateThread , затем привести его обратно в long (обратите внимание, что разыменования указателя не происходит) внутри MyCallbackFunction .