Сейчас на форуме: Rio, tyns777, zombi-vadim (+7 невидимых)

 eXeL@B —› Программирование —› Странное поведение DirectSoundCreate
Посл.ответ Сообщение


Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 04 сентября 2014 23:16
· Личное сообщение · #1

Есть программа работающая с звуком и графикой, однако тупо не умеющая обрабатывать ошибки. Когда тот же DirectSoundCreate возвращает не 0 - всё тупо вылетает с ошибкой. Особенно не приятно то, что до этого переключается видеорежим. Возникла идея реализовать это в отдельном модуле который будет запускаться до переключения видеорежима и выдавать ошибку.
Тестовое delphi приложение работает чётко, однако засунув всё в dll с удивлением заметил, что происходит вход в DirectSoundCreate, а вот выход нет. Всё зависает...
Мне кажется я тупо что-то не учёл, подскажите пожалуйста.
Гуглил безрезультатно, проблема похоже только у меня.




Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 05 сентября 2014 09:20
· Личное сообщение · #2

Ну раз нет ни кода, ничего, будем гадать.
Ткну пальцем в небо, что первое пришло в голову: вызов запихал в DllMain?




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 05 сентября 2014 16:28
· Личное сообщение · #3

Archer пишет:
Ну раз нет ни кода, ничего, будем гадать.
Ткну пальцем в небо, что первое пришло в голову: вызов запихал в DllMain?


Я код не выложил потому, что нормального кода не написал. Пробовал разные варианты:
1) Вызывал DirectSoundCreate(nil, DirectSound, nil) между begin/end. модуля без DllMain
2) Там же делал CreateThread и вызов DirectSoundCreate в потоке.
3) Тоже самое только с ожиданием завершения потока.
4) DirectSoundCreate из DllMain при Dll_Process_Attach
5) CreateThread и вызов DirectSoundCreate в потоке из DllMain при Dll_Process_Attach
6) Тоже самое с WaitForSingleObject(Result,INFINITE);

Пробовал отладчиком. Уходит глубоко в недра DirectSoundCreate, там и остаётся...
Уверен, что большинство из моих попыток, если не все, ошибочны по сути. Буду благодарен если подскажите правильный путь, я его изображу в коде и выложу для более детального разбора ошибки.
p.s. Ещё в расширенном варианте был вызов DirectDrawCreate(nil,DD,nil); так вот с ним проблем никаких не было...



Ранг: 27.8 (посетитель), 13thx
Активность: 0.030
Статус: Участник

Создано: 05 сентября 2014 19:42 · Поправил: microxa
· Личное сообщение · #4

распихать всё в один или два модуля, т.е обойтись без DLL, инициализировать DS перед сменой режима, проверить типы данных/их выравнивание, откатится на старый вариант, перенести всё в тестовое приложение нормально отработавшему DS Create




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 06 сентября 2014 19:48 · Поправил: ToBad
· Личное сообщение · #5

Проект не мой, для меня есть подгрузка мой длл в которой всё хотелось бы сделать.
По идее всё должно быть очень просто, не понятно почему один и тот же код работает в ЕХЕ, но не работает в DLL. Сделать какие то костыли типа из ресурсов длл вытаскивать ехе который проверит ответ от DirectSoundCreate и передаст через клиент\сервер назад в длл я бы мог, но не хочется. Тут теперь дело принципа понять в чём проблема. Я много вариантов directsound.pas скачивал, даже ZenGL прикручивал где тоже есть работа с DirectSoundCreate - результат один, виснет.
Вот простейший код который по идее должен был бы работать:
Code:
  1. library testlib;
  2.  
  3. uses windows, directsound;
  4.  
  5. Var DirectSound: IDirectSound;
  6.  
  7. begin
  8. if DirectSoundCreate( nil, DirectSound, nil ) <> DS_OK Then messagebox(0,'error','',0) else messagebox(0,'ok','',0);
  9. end.


Ни один messagebox не появляется...
Вообще моя цель проверить минимальным кодом доступность DX и правильность установки аудио и видео драйвера. Как я писал ранее основное приложение которое работает с моей длл использует DirectSoundCreate + DirectDrawCreate и тупо не обрабатывает ошибок.

p.s. Сейчас проверил, если запихнуть DirectSoundCreate в экспортируемую функцию и вызвать её после загрузки библиотеки - работает. Но из мой длл никаких функций не вызывается, она просто прописана в импорте ЕХЕ. Как сделать что бы это сработало при загрузке DLL через LoadLibrary?

Добавлено спустя 3 часа 7 минут
Прочитал статью и понял, что вся проблема из за DllMain.
Можно ли это как то обойти без вызова экспортируемой функции? Какой нибудь таймер инициировать в DllMain что бы запускал функцию когда уже можно будет???



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 07 сентября 2014 03:24 · Поправил: dosprog
· Личное сообщение · #6

Идиотизм конечно, всё равно обработка будет в DllMain,
но можно всякие телодвижения выполнять не в этой DLL по её LoadLibrary, а по FreeLibrary в другой, импортируемой этой первой.
То есть в DllMain той второй по получении DLL_PROCESS_DETACH.
Тогда Dll'ей две штуки, первая при загрузке делает free второй, которую она же и импортировала, ну и ...
Не знаю, что это даст. Врядли что-то путное.
Да и в статье предостерегают от этого.

Во второй DLL:
Code:
  1. LibMain proc instance:DWORD,reason:DWORD,unused:DWORD 
  2.  
  3.     .if reason == DLL_PROCESS_ATTACH
  4.       push instance
  5.       pop hInstance
  6.       mov eax, TRUE
  7.  
  8.     .elseif reason == DLL_PROCESS_DETACH
  9.  
  10. !!! ЗДЕСЬ !!!
  11.  
  12.     .elseif reason == DLL_THREAD_ATTACH
  13.  
  14.     .elseif reason == DLL_THREAD_DETACH
  15.  
  16.     .endif
  17.  
  18.     ret
  19.  
  20. LibMain endp





Ранг: 2014.5 (!!!!), 1278thx
Активность: 1.340.25
Статус: Модератор
retired

Создано: 07 сентября 2014 09:25
· Личное сообщение · #7

ToBad пишет:
Прочитал статью и понял, что вся проблема из за DllMain

Ну вообще это я сразу и написал. Не стоит туда пихать, что не попадя. А надо взять и почитать официальную документацию. И таймеры тут не помогут. http://msdn.microsoft.com/en-us/library/windows/desktop/ms682583(v=vs.85).aspx и http://msdn.microsoft.com/en-us/library/windows/desktop/dn633971(v=vs.85).aspx



Ранг: 431.7 (мудрец), 390thx
Активность: 0.730.32
Статус: Участник

Создано: 07 сентября 2014 09:33
· Личное сообщение · #8

Да оно ведь и не сильно усложится, если вствить в екзек дополнительно вызов экспортируемой функции..




Ранг: 450.3 (мудрец), 13thx
Активность: 0.20
Статус: Участник

Создано: 07 сентября 2014 17:06
· Личное сообщение · #9

dosprog пишет:
То есть в DllMain той второй по получении DLL_PROCESS_DETACH.


Тоже самое получается, умирает на DirectSoundCreate. [img]https://exelab.ruimg/smilies/s9.gif[/img]

Archer пишет:
Ну вообще это я сразу и написал. Не стоит туда пихать, что не попадя. А надо взять и почитать официальную документацию. И таймеры тут не помогут.


То есть без вызова экспортируемой функции вообще ничего не получится? Никакие костыли не сработают?

Добавлено спустя 1 час 42 минуты
Сработали вот какие костыли:
1) В DllMain моей библиотеки создаётся поток, который ожидает когда EXE подгружающий DLL будет распакован (проверяет наличие кода в определённом месте). Это работало и ранее, для небольшого патча ЕХЕ.
2) Когда можно патчить, делаю jmp на мою процедуру из DLL поблизости от EntryPoint EXE файла.
3) В этой функции делаю проверку на DirectSoundCreate и DirectDrawCreate, выдаю месседж и на выход если не ОК либо выполняю код который был под JMP и возвращаюсь на следующие инструкции в EXE.

Добавлено спустя 1 час 47 минут
То есть как и должно было бы быть в нормальном варианте если бы EXE вызывал функцию из моей DLL, а не просто её подгружал. Так как он этого не делал - пришлось из DllMain это добавить.


 eXeL@B —› Программирование —› Странное поведение DirectSoundCreate
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати