Код (Text): .data hThread dd 0 .code invoke CreateThread,NULL,NULL,addr ThreadProc,NULL,0,addr hThread ThreadProc proc lParam:dword PrintText "HERE" ;пишет, что в процедуру попали ret ;программа вылетает ThreadProc endp Собственно сам вопрос: почему программа вылетает при возвращении из потока? Пробовал через GetExitCodeThread-> ExitThread - всё равно вылетает, пробовал TerminateThread - тот же результат.
Посмотри пример айселона Х:\masm32\icztutes\TUTE15\THREAD.ASM Может поймеш mov eax,OFFSET ThreadProc invokeCreateThread,NULL,NULL,eax,\ NULL,NORMAL_PRIORITY_CLASS,\ADDR ThreadID invoke CloseHandle,eax ThreadProc PROC USES ecx ParamWORD mov ecx,300000000 Loop1: add eax,eax dec ecx jz Get_out jmp Loop1 Get_out: invoke SendMessage,hwnd,WM_FINISH,NULL,NULL ret ThreadProc ENDP
ssx ret 4 тоже пробовал - не помогло. VOOrDOOluck Видел я это. И что тут можно такого сокровенного найти? Чем принципиально отличается Icezelion'овский пример от моего вызова? hThread возвращается нормально,процедура вызывается правильно,что положено выполняет. Тем что там CloseHandle? Мне хэндл ещё нужен, поэтому не закрываю. Разницы в применении offset и addr в данном случае нет. Перепробовал все варианты.
cresta Если б вместо твоей PrintText "HERE" там стоял MessageBox и ты спрашивал бы, то было бы понятно, но нихрена ведь неизвестно что творится у тебя в PrintText "HERE", бери дебаггер и проверяй. ssx > ThreadProc() же передается 1 параметр. ret 4 наверное надо Это ж masm однако, там и будет ret 4 после компиляции.
А почему бы не заиметь какой-нибудь Event, созданный, как NotSet и ожидать после вызова CreateThread WaitFor..этот Event. А в ThreadProc в конце поставить SetEvent. Кажется будет работать. Или чё нитак понял.
Asterix Это просто пустая процедура для примера(чтобы не заваливать топик), чтобы понять, почему не возвращается, на деле в процедуре работает цикл, и достаточно долго. И при некоторых обстоятельствах бывает необходимо прервать этот поток, чтобы перезапустить снова, уже с другими параметрами. Поэтому хэндл нужен. Есть или нет PrintText - ничего не меняется, он только для того, чтобы показать, что вызов прошёл нормально. Случайно определил, что поток нормально отрабатывает и нормально, безо всяких коллизий возвращается, если создается в каком - либо другом месте кода. Отсюда вопрос: как влияет на создание и завершение потока конкретное место, откуда он запускается? Разве не всё равно, откуда вызывать CreateThread?
Asterix Это просто пустая процедура для примера(чтобы не заваливать топик), чтобы понять, почему не возвращается, на деле в процедуре работает цикл, и достаточно долго. И при некоторых обстоятельствах бывает необходимо прервать этот поток, чтобы перезапустить снова, уже с другими параметрами. Поэтому хэндл нужен. Есть или нет PrintText - ничего не меняется, он только для того, чтобы показать, что вызов прошёл нормально. Случайно определил, что поток нормально отрабатывает и нормально, безо всяких коллизий возвращается, если создается в каком - либо другом месте кода. Отсюда вопрос: как влияет на создание и завершение потока конкретное место, откуда он запускается? Разве не всё равно, откуда вызывать CreateThread?
Black_mirror В аттаче 3 процедуры - две из которых вызывается, и одна, которая вызывается. _1187373562__tmp.asm
cresta Согласен с Asterix. + в PrepareIndex ты не используешь диапазон из lParam, а всегда используешь [0...Cnt], что содержит Cnt при вызове потока из ListProc?
Asterix я пробовал делать pushad/popad+push edi&esi/pop edi&esi, пробовал uses, т.к. видел, что регистры меняются все. Да и в варианте с нормальным вызовом и возвратом я ведь не сохраняю ebx тоже, как с этим быть? И при этом работает. q_q Cnt содержит кол-во файлов найденых поиском. В одном случае (из ListButtProc) запрашиваю сразу для всех индексы иконок, а в другом (из ListProc) только для тех, кто обозначился по LVN_ODCACHEHINT т.е. от .iFrom до .iTo. Пробовал в обоих вариантах использовать передачу диапазона как через lParam, так и через глобальную переменную.
cresta а в другом (из ListProc) только для тех, кто обозначился по LVN_ODCACHEHINT т.е. от .iFrom до .iTo. Но при этом внутри PrepareIndex используешь Cnt, а не lParam. Ты уверен, что Cnt содержит допустимое значение? Другое возможное объяснение, что пришло несколько LVN_ODCACHEHINT и запущено несколько PrepareIndex, а что они могут натворить неизвестно.
cresta Ты передаёшь разные параметры в функцию, причем в одном случае она у тебя работает в другом нет, можно предположить что косяк в тех параметрах что ты передаешь. А что до регистров, esi,edi,ebx в случае использования обязательно нужно сохранять, например в ListProc достаточно было написать uses esi edi ebx и не push'ить/pop'ить далее их в процедуре, masm сделает за тебя всё сам. И ещё советую не юзать макросов в таком количестве, особенно не своих, ибо не зная логики их написания и работы ты можешь нарваться на косяк, потому что в них часто находят ошибки, также как и в либе masm32.lib
Asterix предположить что косяк в тех параметрах что ты передаешь lParam внутри PrepareIndex не используется.
q_q В том случае, когда работает(из ListButtProc) у меня есть уже полное количество-1 (Cnt), поэтому сразу для всех заряжаю. Т.е. от 0 до <количество>-1 Я проверял это: если не трогать скролл LVN_ODCACHEHINT приходит только один раз. Поток не перезапускается. И пробовал искуственно перезапустить в рабочем варианте поток, не ожидая завершения предыдущего. Ничего страшного в этом нет, просто ещё раз пробежал цикл и вернулся. Да и согласно Icezelion'а допускается несколько одновременно запущенных одноименных потоков. Asterix Проблема не в процедуре как таковой, она свое дело делает, при любых входных параметрах, и можно отследить каждый проход цикла в ней, всё происходит верно, вот только возврат не получается. Или может получается, но неизвестно куда. C вытекающими отсюда последствиями.
cresta допускается несколько одновременно запущенных одноименных потоков В теории этот так. В реальной жизни надо смотреть на функцию потока. В твоем случае она использует глобальную переменную hIconMem. Вообще трудно судить о возможных проблемах не имея полного исходного текста, не имея возможности его собрать и посмотреть на работу в отладчике.
q_q > не имея возможности его собрать Угу, к тому же из-за использования кучи макросов не каждый может это собрать, мне например лениво ставить следующий после 8.0 masm32, опять перегонять инклуды и т.д.