Speccy - наш выбор!

Speccy - наш выбор! (http://zx-pk.ru/index.php)
-   Эмуляторы отечественных компьютеров (http://zx-pk.ru/forumdisplay.php?f=61)
-   -   Эмулятор терминала типа VT52 (http://zx-pk.ru/showthread.php?t=20092)

Titus 2nd January 2013 19:48

Quote:

Originally Posted by Patron (Post 564016)
А зачем это надо в данном случае, когда хук (по идее) должен устанавливаться вызовом LoadLibrary.

Создаётся файл лога после вызова LoadLibrary ?

Затем, что эта библиотека мне только для примера, я на ее основе делаю свою. А мне нужна функция еще одна там.

Пробовал размещать в виде:

Code:

extern LRESULT CALLBACK FuncName()
Но она через :
Code:

hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "FuncName")
Не видится.

---------- Post added at 18:35 ---------- Previous post was at 18:34 ----------

Quote:

Originally Posted by Patron (Post 564016)
Судя по тому, что хуки у VisualStudio прекрасно работают из EXE - там всё так и есть.

Судя по тому, что с работой в составе .exe есть глюки - не все так просто. Сделаю если в виде либы - станет понятнее.

---------- Post added at 18:48 ---------- Previous post was at 18:35 ----------

Quote:

Originally Posted by Titus (Post 564018)
Пробовал размещать в виде:

Code:

extern LRESULT CALLBACK FuncName()

Причем ключевое слово __declspec(dllexport) тоже не помогает почему-то пока что.

Patron 2nd January 2013 20:01

Если добавить в код DLL такие строки:

Code:

#define EXPORT extern "C" __declspec(dllexport)

EXPORT int GetInt2()
{
        return 2;
}

А в код программы такие:
Code:

typedef int (__cdecl* int_DllFun_void)( void );

HLIB hLib = LoadLibrary("XXX.dll");

int_DllFun_void GetInt2 = (int_DllFun_void) GetProcAddress( hLib, "GetInt2" );

int nInt = GetInt2();

То в последней строчке функция GetInt2() должна вернуть число '2'.

Проблема экспорта функций из DLL в том, что для каждой разновидности экспортируемых функций нужно иметь правильный тип ( выделен синим ). Красным выделены тип возвращаемого значения и типы аргументов экспортируемой функции.

---------- Post added at 18:01 ---------- Previous post was at 17:55 ----------

Quote:

Originally Posted by Titus (Post 564018)
Судя по тому, что с работой в составе .exe есть глюки - не все так просто.

Хук и в EXE, и в DLL - работает абсолютно одинаково.

Titus 2nd January 2013 20:28

Quote:

Originally Posted by Patron (Post 564027)
Проблема экспорта функций из DLL в том, что для каждой разновидности экспортируемых функций нужно иметь правильный тип ( выделен синим ). Красным выделены тип возвращаемого значения и типы аргументов экспортируемой функции.

Правильный тип нужен для использования функции. А у меня даже указатель на нее не получалось получить. Сейчас попробую с "C".

---------- Post added at 19:04 ---------- Previous post was at 19:01 ----------

Да, с extern "C" __declspec(dllexport) получилось,
а с __declspec(dllexport) не получалось.

---------- Post added at 19:13 ---------- Previous post was at 19:04 ----------

Quote:

Originally Posted by Patron (Post 564027)
Хук и в EXE, и в DLL - работает абсолютно одинаково.

В общем, похоже, что все так и есть.

Попробовал подключить твою либу к своему эмулятору, при открытии ее (а следовательно и при инициализации еешного хука), все так же начинает глючить, как и при собственном хуке, который был в .exe.
Т.е. при активном окне эмулятора все окей, при активном окне консоли - тормоза и невызывание хука (в лог ничего не пишется).

Но тут я вспомнил твои слова о том, что при отсутствии опроса сообщений хук не работает. И таки да - в режиме консоли у меня сообщения, идущие эмулятору не опрашиваются. Т.е. они опрашиваются, но только когда выполняется какая-либо команда консоли. Значит собака зарылась здесь, и надо понять КАКИМ образом тормоза и глюки хуков зависят от невызывания разбора сообщений.

---------- Post added at 19:28 ---------- Previous post was at 19:13 ----------

Причем, хук, запущенный в другой программе (например тесте хуков) работает исправно.

Patron 2nd January 2013 21:08

Quote:

Originally Posted by Titus (Post 564031)
хук, запущенный в другой программе (например тесте хуков) работает исправно.

Там свой (работающий в этот момент) разборщик сообщений.

---------- Post added at 19:08 ---------- Previous post was at 19:04 ----------

Можно запускать хук в отдельном потоке со своим разборщиком сообщений - это самое простое решение, которое "уравнивает в правах" поток хука с хуком во внешнем процессе.

Titus 2nd January 2013 21:09

Quote:

Originally Posted by Patron (Post 564049)
Там свой (работающий в этот момент) разборщик сообщений.

Но хук - вещь не относящаяся к конкретной программе, просто звено в цепочке обработки, никак (если исходить из доки) не завязанная с сообщениями конкретному окну.

Patron 2nd January 2013 21:17

Код потока хука может выглядеть так:
Code:

dword WINAPI HookThread( LPVOID pArg )
{
        ghKeyboardHook = SetWindowsHookEx( WH_KEYBOARD_LL, KeyboardHook, ghInstance, 0);

        MSG      msg;
        for(;;)
        {
                if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
                {
                        TranslateMessage( &msg );
                        DispatchMessage( &msg );
                        if( msg.message == WM_QUIT ) break;
                }

                Sleep(1);
        }

        UnhookWindowsHookEx( ghKeyboardHook );

        return 0;
}

А код его запуска в основной программе - так:
Code:

HANDLE hHookThread = CreateThread( NULL, 0, HookThread, NULL, 0, NULL );


---------- Post added at 19:17 ---------- Previous post was at 19:17 ----------

Quote:

Originally Posted by Titus (Post 564051)
Но хук - вещь не относящаяся к конкретной программе, просто звено в цепочке обработки, никак (если исходить из доки) не завязанная с сообщениями конкретному окну.

Судя по всему - доки по хукам безнадёжно устарели.

Titus 2nd January 2013 21:19

Немножко поэкспериментировал.

Все застревает на функции PeekMessage(), если она не вызвана вовремя.

Я думаю так: если процесс не отвечает на сообщения, то он считается зависшим, и хук, находящийся в экзешнике этого процесса отключается.

Если процесс снова начинает отвечать на сообщения, то хук восстанавливается, но с небольшой задержкой. Эта задержка внутри PeekMessage и подтормаживает систему.

Patron 2nd January 2013 21:21

Хотя, наверняка, потоку хука можно делать блокирующий вызов GetMessage вместо не блокирующего вызова PeekMessage. Есть смысл сначала сделать с PeekMessage и Sleep(1), а потом с GetMessage.

Titus 2nd January 2013 21:34

Quote:

Originally Posted by Patron (Post 564054)
Судя по всему - доки по хукам безнадёжно устарели.

Как это устарели? Просто много чего недокументированно.

---------- Post added at 20:34 ---------- Previous post was at 20:23 ----------

Ура! Вот в таком виде прекрасно работает и не виснет:

Code:

UINT32 WINAPI HookThread(LPVOID pArg)
{
        hhKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHook, hInst, 0);

        MSG        msg;

        while (true)
        {
                GetMessage(&msg, NULL, 0, 0);
                TranslateMessage(&msg);
                DispatchMessage(&msg);

                if( msg.message == WM_QUIT ) break;
        }

        UnhookWindowsHookEx( hhKeyboardHook );

        return 0;
}

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

Как убить созданный поток, послав ему честный WM_QUIT?

Patron 2nd January 2013 21:53

Quote:

Originally Posted by Titus (Post 564058)
Как убить созданный поток

Надо вставить туда печать в файл и проверить, закрывается ли он сам при выходе из программы.


All times are GMT +4. The time now is 02:42.

Powered by vBulletin® Version 3.8.3
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.