Russian Qt Forum
Сентябрь 25, 2024, 22:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Странность WaitForSingleObject  (Прочитано 5970 раз)
Mityai
Гость
« : Март 29, 2010, 15:05 »

Доброго всем времени суток! Проблема такого рода. Есть 2 приложения, одно создает событие, другое к нему обращается:

Создатель:
Код:
#include <QtCore/QCoreApplication>
#include <afxres.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    bool b = false;
    LPCTSTR str = (LPCTSTR)"Event";

    HANDLE WriteEvent = CreateEvent(NULL, FALSE, FALSE, str);

    DWORD ddd;

    while (1)
    {
        ddd = WaitForSingleObject(WriteEvent, 1000);
        if (ddd != 0x00000102L)
            b = true;
    }
    return 0;
}

Обращающийся:
Код:
#include <QtCore/QCoreApplication>
#include <afxres.h>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    bool create = false;

    LPCTSTR str = (LPCTSTR)"Event";

    while (!create)
    {
        HANDLE Event = OpenEvent(EVENT_ALL_ACCESS, FALSE, str);

        int i = GetLastError();

        if (Event != 0x00000000)
        {
            SetEvent(Event);
            create = true;
        }
    }

    return 0;
}

Проблема том, что при замене в создателе while(1) на while(!b) или, скажем, на while (ddd != 0x00000102L) отлов события не происходит, хотя по вечному циклу while (1) он идет превосходно. Подскажите, пожалуйста, в чем здесь проблемка-то??? Заранее извиняюсь, если моя терминология насчет событий некорректна.

Да, GetLastError() в обращающемся возвращает 2, как будто Event не создан, и если в if внутри while (1) добавить break, опять же отлов события не произойдет.
« Последнее редактирование: Март 29, 2010, 15:23 от Mityai » Записан
alexman
Гость
« Ответ #1 : Март 29, 2010, 21:03 »

Завязывай с WINAPI Подмигивающий
Записан
Mityai
Гость
« Ответ #2 : Март 30, 2010, 08:32 »

Завязывай с WINAPI Подмигивающий

Дык самое обидное, что Win32 Console, собранная под стандартным MSVS 2005 с таким же кодом, прекрасно работает! Злой
Записан
Mityai
Гость
« Ответ #3 : Март 30, 2010, 08:47 »

Каюсь, не думал, что проблема в этом. Отказывается работать в том случае, если вслед за циклом идет объявление еще одного хэндла:

HANDLE hMapped = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
                                                    PAGE_READWRITE, 0, 1048576,
                                                    ((const WCHAR*)"map"));

Создание проецируемого файла - вещь необходимая, ради нее сихронизация SingleObject и затевалась. Что делать?
Записан
Akaiten
Гость
« Ответ #4 : Март 30, 2010, 09:35 »

Я бы написал так:
Код
C++ (Qt)
while (!b)
{
   ...
   if (ddd == WAIT_OBJECT_0)
       b = true;
   else { /* обработка ошибок */ }
}
 

Проверь наличие ошибок при вызове CreateEvent, OpenEvent, SetEvent и т.п.
Записан
Mityai
Гость
« Ответ #5 : Март 30, 2010, 09:43 »

Проверь наличие ошибок при вызове CreateEvent, OpenEvent, SetEvent и т.п.

Код:
    LPCTSTR str = (LPCTSTR)"Event";

    HANDLE hWriteEvent = CreateEvent(NULL, FALSE, FALSE, str);

    int i = GetLastError();

    DWORD ddd = 0x00000102L;

    while (ddd == 0x00000102L)
    {
        ddd = WaitForSingleObject(hWriteEvent, 1000);
    }

    HANDLE hMappedFlying = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
                                             PAGE_READWRITE, 0, 1048576,
                                             ((const WCHAR*)"map_flying"));

i = 0, создает корректно. А OpenEvent, Как я уже писал выше, выдает ошибку за номером 2, событие не существует.

Меня всё же терзают сомнения, что есть какой-то косяк при работе с более чем одним HANDLE.
Записан
Akaiten
Гость
« Ответ #6 : Март 30, 2010, 12:11 »

Попробуй в OpenEvent указать права доступа EVENT_MODIFY_STATE вместо EVENT_ALL_ACCESS, и лучше использовать более специфичное имя вместо "Event".
Записан
Rcus
Гость
« Ответ #7 : Март 30, 2010, 16:33 »

Хм... а компилятор не ругается на то что const char[] преобразуют к const WCHAR* (где sizeof(WCHAR) == 2).
Я вполне могу себе представить такую ситуацию при линковке когда за строкой "Event" не будет трех 0x00 подряд.
Записан
Mityai
Гость
« Ответ #8 : Март 30, 2010, 16:43 »

Хм... а компилятор не ругается на то что const char[] преобразуют к const WCHAR* (где sizeof(WCHAR) == 2).
Я вполне могу себе представить такую ситуацию при линковке когда за строкой "Event" не будет трех 0x00 подряд.

Не ругается... Была уже с этим подобная проблема, когда CreateFileMapping делал - там преобразовывалось некорректно. Здесь в дебаге проверял - вроде как присваивает одинаково в обоих приложениях.

Попробуй в OpenEvent указать права доступа EVENT_MODIFY_STATE вместо EVENT_ALL_ACCESS, и лучше использовать более специфичное имя вместо "Event".

Это не пробовал, надо будет проверить. Хотя даже если и так, все равно не понятно почему при while(1) работает, а иначе нет.
Записан
Mityai
Гость
« Ответ #9 : Март 31, 2010, 09:54 »

Хм... а компилятор не ругается на то что const char[] преобразуют к const WCHAR* (где sizeof(WCHAR) == 2).
Я вполне могу себе представить такую ситуацию при линковке когда за строкой "Event" не будет трех 0x00 подряд.

Спасибо, Rcus, за наводку. Проблема вознимает действительно в момент преобразования текста в CreateFileMapping. Заменил HANDLE создания маппинга на
Код:
LPCTSTR str2;
str2 = (LPCTSTR) "map_flying";
и получил такой же результат. Только как с этим бороться всё равно не понятно Непонимающий

-------------------------------------------------------------------------------------

Для MSVS2005 нашел корректно работающее преобразование:
Код:
	
CString s;
LPCTSTR lp;
s="throw";
lp = (LPCTSTR) s;
Большой я чайник. Плачущий Сейчас буду разбираться с Qt...
« Последнее редактирование: Март 31, 2010, 10:10 от Mityai » Записан
Rcus
Гость
« Ответ #10 : Март 31, 2010, 10:08 »

Подсказки уже были даны... Либо используйте LPCSTR и *A варианты вызовов (что по идее deprecated), либо LPCTSTR, оборачивайте литералы в _T/_TEXT и используйте макро-имена для вызовов, либо LPCWSTR, и *W варианты вызовов (при этом нужно писать L перед строковыми литералами).
Записан
Mityai
Гость
« Ответ #11 : Март 31, 2010, 10:15 »

Подсказки уже были даны... Либо используйте LPCSTR и *A варианты вызовов (что по идее deprecated), либо LPCTSTR, оборачивайте литералы в _T/_TEXT и используйте макро-имена для вызовов, либо LPCWSTR, и *W варианты вызовов (при этом нужно писать L перед строковыми литералами).
Изначально литералы использовал и какой-то подобный косяк словил. Там тоже проблем своих хватает. Хотя, может тоже где-то ошибся. Кода не осталось, поэтому проверить не могу. В любом случае спасибо большое за помощь!
Записан
Mityai
Гость
« Ответ #12 : Март 31, 2010, 14:00 »

Проблема решается объявлением LPCTSTR следующим образом:
Код:
LPCTSTR str = L"Event";
Rcus, ещё раз спасибо за наводку! Всем удачи, не наступайте на чужие грабли! Веселый
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.108 секунд. Запросов: 21.