2014-01-26 6 views
3

Если написать простой код, как это:CreateEventW неожиданно терпит неудачу

int main(int argc, char* argv[]) 
{ 
    HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, L"EVENTTEST"); 
    if (hEvent==NULL){ 
      cout<<"Error "<<GetLastError(); 
    } 
    else{ 
      cout<<"Success"; 
    } 

    getch(); 
    return 0; 
} 

код работает с успехом сообщения, но если я добавить объявление в общем объеме выше основной (здесь я только добавить строку кода, объявив переменная bool) функция CreateEvenetW Fails с кодом ошибки 998. Если я использую CreateEvent вместо CreateEventW, проблема не возникнет. Но я хочу знать, что происходит с CreateEventW, когда я добавить простую переменную декларацию, как это:

bool x=true; 
int main(int argc, char* argv[]) 
{ 
    HANDLE hEvent = CreateEventW(NULL, FALSE, FALSE, L"EVENTTEST"); 
    if (hEvent==NULL){ 
      cout<<"Error "<<GetLastError(); 
    } 
    else{ 
      cout<<"Success"; 
    } 

    getch(); 
    return 0; 
} 

Эти странные и неожиданные ошибки беспокоит меня об использовании некоторых функций WinAPI.

Я должен упомянуть код компилируется в Borland C++ 6

EDIT: Если я объявить переменную без инициализации (например: BOOL х) ошибка не происходит. Также эта проблема возникает только с некоторыми типами данных. Я проверил типы (int, double), а программа запускалась с сообщением «Успех». Но типы (char, bool) приводят к ошибке при их инициализации.

+4

Возвращаемые значения документируются [здесь] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682396 (v = vs.85) .aspx), но 998 не среди них (998 - ERROR_NOACCESS). Хотя функции ведут себя по-другому, просто из-за 'bool x = true' звучит скорее как проблема с компилятором из 2002 http: //en.wikipedia.org/wiki/C% 2B% 2BBuilder –

+0

@herohuyongtao Я * умираю *, чтобы знать, что это связано с прямым вызовом Unicode-версии 'CreateEvent' с жестким Unicode-именем. Скажите plz. – WhozCraig

+0

GetLastError возвращает 998, а отсюда http://msdn.microsoft.com/en-us/library/windows/desktop/ms681388(v=vs.85).aspx вы можете видеть, что он говорит: Недействительный доступ к ячейке памяти. – user2808671

ответ

1

Отказ от ответственности: Это выстрел в темной догадке.

Поскольку вы создаете именованное событие («EVENTTEST»), какой-то другой процесс (возможно, все еще работает) может создать событие с другим набором разрешений. Возможно, один экземпляр запускался в командной оболочке с правами администратора, а неудавшийся экземпляр - нет?

Другими словами, это какая-то проблема безопасности/ACL с именованными дескрипторами ядра.

Еще одно предположение: линия «x = true» - это просто красная селедка, и проблема несколько зависит от времени.

Вы можете проверить журналы событий (Панель управления-> Администрирование-> Просмотр событий). Затем проверьте журналы приложений, системы и безопасности в папке «Журналы Windows». Это может показать что-то ...

В противном случае перезагрузитесь и повторите попытку. И если вам не нужно, чтобы дескриптор события работал в разных процессах, просто замените «EVENTTEST» на NULL и дайте потокам внутри одного процесса просто передать дескриптор.

+0

Спасибо за ваш ответ. Но я много раз проверял этот код на двух разных компьютерах с одинаковым результатом. всякий раз, когда я удаляю эту строку, функция завершается успешно, когда снова добавляется эта строка, в которой она терпит неудачу ... Согласно тому, что вы упомянули, я устанавливаю последний параметр в NULL, и ошибка уходит. Но мне нужно, чтобы событие имело имя. Если другой экземпляр программы запускается, то, проверяя это событие, он должен закрыться. Я не хочу больше одного экземпляра для моей исполняемой программы. В любом случае, я также проверю системные журналы. – user2808671

+0

Я посмотрел журналы окон, но не нашел ничего, относящегося к вопросу – user2808671

2

Ошибка 998 в программе Windows указывает очень серьезная проблема. Вы получите это, когда само ядро ​​может сказать, что куча процесса повреждена. Обычно это сгенерировано вместо обычного нарушения прав доступа, которое вы получите для повреждения кучи, когда программа не находится в состоянии, когда она не может безопасно генерировать исключение AV. Это происходит прежде всего, когда загрузчик Windows занят загрузкой DLL и запускает точку доступа DllMain(). Некоторые шансы, что ваш отладчик показывает уведомление об исключении из первого шанса. Надеюсь, в любом случае.

Вы, конечно, никогда не получите повторную копию этой ошибки с кодом, который вы опубликовали, проблема вызвана другим кодом. Либо внутри DLL (скорее всего), так и в коде инициализации, который выполняется до того, как будет введена функция main(). Коррупция кучи - это, конечно, стандартная проблема на C++. Вы, вероятно, найдете помощь от инструмента Application Verifier. Удачи вам.

+0

Как я уже говорил, этот ПРОСТОЙ код работает и не работает. Конечно, это небольшая часть большого проекта, но у этого кода есть проблема, о которой я говорил. То, что перед этим кодом является лишь некоторыми, включает определения и не более того. – user2808671

+2

Избегайте кричать. Я никогда не говорил, что это был ваш код, который имел проблему. В процессах никогда не бывает недостатка в вшивании библиотек DLL. Я дал вам очень конкретную рекомендацию по устранению неполадок, что сказал вам AppVerifier? –

+0

Я не орал приятель. Отчет журнала AppVerifier сообщает об ошибке и отсутствии предупреждения – user2808671

Смежные вопросы