Консольное приложение рушится при закрытии

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Консольное приложение рушится при закрытии

Сообщение VBTerminator » 09.07.2010 (Пт) 21:24

С помощью API я создаю консольное окно (чёрное окно в стиле DOS'а).
Но при закрытии консоли как нажатием на "крестик" в правом верхнем углу окна, так при её уничтожении с помощью CloseHandle IDE намертво зависает. Скомпилированную программу постигает та же участь.

Что у меня не так?
Вложения
Сервер авторизации.zip
(7.28 Кб) Скачиваний: 41

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Консольное приложение рушится при закрытии

Сообщение Хакер » 09.07.2010 (Пт) 21:52

Что заслуживают люди, использующие константу vbNull как NULL, которая на самом деле означает не NULL, а подтип Variant-а «Null», и поэтому равна единице, сожаления или осмеяния?

Что заслуживают люди, выкладывающие код с такой грубой ошибкой во всевозможных справочниках? Однозначно порицания.

Какую великую, хитрую и в то же время ужасную цель преследует человек (да, ты, VBTerminator), закрывающий хендл stdout-а, освобождающий консоль и сразу же после этого делющий ConsoleWriteLine, а чуть позже — даже чтение из консоли?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

VBTerminator
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 415
Зарегистрирован: 19.11.2008 (Ср) 20:10

Re: Консольное приложение рушится при закрытии

Сообщение VBTerminator » 10.07.2010 (Сб) 7:22

Хакер писал(а):Что заслуживают люди, использующие константу vbNull как NULL, которая на самом деле означает не NULL, а подтип Variant-а «Null»

А что тогда использовать?

Хакер писал(а):Какую великую, хитрую и в то же время ужасную цель преследует человек (да, ты, VBTerminator), закрывающий хендл stdout-а, освобождающий консоль и сразу же после этого делющий ConsoleWriteLine, а чуть позже — даже чтение из консоли?

А какие внутренние причины заставляют жить приложение даже после отработки Form_Unload и уничтожения консоли? Здравый смысл подсказывал мне, что после этого приложение должно завершиться.

И как тогда его завершить (кроме End'а, о котором составлено не очень хорошее впечатление)?

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Консольное приложение рушится при закрытии

Сообщение Хакер » 10.07.2010 (Сб) 9:08

VBTerminator писал(а):А что тогда использовать?

Можно двадцать пять тысяч двести сеьмдесят шесть. Эффект тот же.

Здравый смысл подсказывал мне, что после этого приложение должно завершиться.

Не здравый смысл, а больная глупость.

Полное непонимание того, как работают, выполняются программы.
1) Сделай пошаговую трассировку.
2) У тебя цикл Do/Loop. Он бесконечный. Нет условия выхода из него. Нет Exit Do. С какой радости программа должна выйти из этого цикла?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Re: Консольное приложение рушится при закрытии

Сообщение alibek » 10.07.2010 (Сб) 9:10

VBTerminator писал(а):А что тогда использовать?

Обычно используют ByVal 0&.
Или, более правильно, Const C_NULL As Long = 0&
Lasciate ogni speranza, voi ch'entrate.

Денис
Доктор VB наук
Доктор VB наук
Аватара пользователя
 
Сообщения: 2734
Зарегистрирован: 07.11.2006 (Вт) 13:55
Откуда: Ейск, Краснодарский край

Re: Консольное приложение рушится при закрытии

Сообщение Денис » 12.07.2010 (Пн) 9:13

Ха-ха! На башорге бы посоветовали использовать тупо 0 (ноль)
Программирование — богоизбранная дисциплина! Если бог и есть, то вселенную он скомпилировал, не иначе.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Консольное приложение рушится при закрытии

Сообщение Vi » 12.07.2010 (Пн) 11:59

Хакер писал(а):Что заслуживают люди, использующие константу vbNull как NULL, которая на самом деле означает не NULL, а подтип Variant-а «Null», и поэтому равна единице, сожаления или осмеяния?


И какая разница-то в контексте функции?

"lpNumberOfCharsRead As Long" как представление Сишного "LPDWORD lpNumberOfCharsRead" требует указателя для приёма значения, и, учитывая описание в MSDN "lpNumberOfCharsRead / [out] Pointer to a variable that receives the number of TCHARs actually read", его начальное значение не имеет значения. По крайней мере VB передаст правильный указатель на число и оно будет изменено на новое значение. Это, конечно, плохая мысль - не использовать возвращаемые MS значения, но не смертельно в данном случае.

"lpReserved As Any" как представление Сишного "LPVOID lpReserved" снова требует указателя (в общем-то, судя по названию параметра, не используемого), поэтому VB передаст правильный указатель на нечто, функции безразличное. В данном случае, действительно, указатель на Variant, содержащий VT_NULL. Единственное требование, которое не выполняется, это описание в MSDN "lpReserved / [in] Reserved; must be NULL", но оно в данном случае не критично, хотя в некоторых других случаях функции требуют явного соблюдения соглашения.

Т.о., скорее всего, взяли кусок из какого-то работоспособного кода и внедрили в свою программу. Поэтому это твоё презрение должно быть отправлено авторам такого использования функции, а не самому VBTerminator-у.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Консольное приложение рушится при закрытии

Сообщение Хакер » 12.07.2010 (Пн) 12:38

Vi, почему ты всегда пытаешься ко мне придраться?

По крайней мере VB передаст правильный указатель на число и оно будет изменено на новое значение.

То, что в данное случае передаётся, это вообще не то, на что я обращаю внимание своим постом. Я же говорю о кочующей заразительной частице глупости, которая заставляет людей использовать константу vbNull как полный аналог сишной константы NULL. Людей, которые даже не догадываются посмотреть реальное (а не кажущееся им) значение vbNull.

функции безразличное.

Как бы не так?

Когда функция/структура имеет зарезервированные параметры/поля, в документации при описании этих полей пишут «MUST be NULL» (обязано быть нулём), а не «Might be anything» (может быть любым). Ты ведь знаешь, почему так делает?

Это делают для того, чтобы когда параметру/полю найдут применение, и оно перестанет быть зарезервированным, система смогла быть отличать старые программы, полагающиеся на то, что у поля нет никакого назначения, от новых программ, которые используют его по новому, недавно появившемуся предназначению.

Вот эта функция как раз одна из тех счастливиц, зарезервированному аргументу которой таки придумали предназначению (большинству не везёт: зарезервированные поля и аргументы остаются навечно зарезервированными, потому что про них забывают).

В старой документации однозначно написано, что параметр зарезервирован и должен обязан быть NULL.
В новой документации уже говорится, что у параметра появилось предназначение — передача указателя на структуру CONSOLE_READCONSOLE_CONTROL. Правда, только для W-реализации.

Если бы автор использовал ReadConsoleW, он бы передал указатель на vbNull, а функция бы посчитала это указателем на CONSOLE_READCONSOLE_CONTROL. И опять ему повезло: первым полем CONSOLE_READCONSOLE_CONTROL идёт поле с длиной структуры, по которому настоящую структуру легко отличить от чего-то, по ошибке пытающегося быть похожим на структуру. А если бы не повезло?

В любом случае, в данном коде мы имеем нарушение спецификации. Написано: при использовании ANSI-версии функции передавать NULL. А нарушениям спецификации — бой.

В общем.

Использование vbNull как NULL — это та глупость, с которой я веду бой.
Передача любой фигни в качестве значения зарезервированных параметров (какая им, дескать, разница, функция всё равно на них не обращает внмания) — это ещё одна глупость, с которой я веду бой.

Последнее — вообще причина того, что с выходом новой версии ОС половина приложений перестают работать. Обыватели обвиняют новую ОС в кривости, но кривость на самом деле присуща головам тех, кто делает подобные допущения и передаёт что-попало в reserved-параметры, как здесь.

То, что в данном случае передача ByRef vbNull не приводит ни к чему плачевному и не является источником описанной проблемы — это вообще ничего не значит. Я критикую наплевательское отношение, а не конкретный код. А источник проблемы я описал позже: бесконечный цикл с попытками читать и писать в закрытые хендлы освобождённой консоли.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vi
Постоялец
Постоялец
 
Сообщения: 739
Зарегистрирован: 25.01.2002 (Пт) 11:03
Откуда: Россия, Ижевск

Re: Консольное приложение рушится при закрытии

Сообщение Vi » 12.07.2010 (Пн) 12:47

Хакер писал(а):Я же говорю о кочующей заразительной частице глупости, которая заставляет людей использовать константы vbNull как полный аналог сишной константы NULL. Людей, которые даже не догадываются посмотреть реальное (а не кажущееся им) значение vbNull.

Тогда было конструктивнее и информативнее дать ссылку на свою статью о различии vbNull и NULL и возможных проблемах при их бездумном смешении.
Хакер писал(а):В любом случае, в данном коде мы имеем нарушение спецификации. Написано: при использовании ANSI-версии функции передавать NULL. А нарушениям спецификации — бой.

Тогда было конструктивнее и информативнее дать ссылку на свою статью о нарушение спецификации и возможных проблемах при этом.
Хакер писал(а):Использование vbNull как NULL — это та глупость, с которой я веду бой.
Передача любой фигни в качестве значения зарезервированных параметров (какая им, дескать, разница, функция всё равно на них не обращает внмания) — это ещё одна глупость, с которой я веду бой.

Бой бою - рознь. И победа в нем иногда сродни поражению.
Vita
Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! (с) КВН


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: AhrefsBot и гости: 93

    TopList