PDA

View Full Version : Hooking Qt Signals/Slots



mlheese
4th October 2010, 16:24
I need to write an app that somehow can 'hook' onto another Qt app to display all the Signals/Slots being emitted/exec'd. Similar to a Spy++ app with windows. It's not possible to map the Signals/Slots inside the app because the Qt app's I'm trying to 'hook' are already older apps we don't want to waste time rewriting/modifying.

I've written Qt code that can hook Qt apps using SetWindowsHookEx() but it cannot display the emitted Signals.

Is there any methods for hooking an existing Qt app to view the Signals being emitted?

Thanks,
Mike H
mheese@efji.com

squidge
4th October 2010, 17:53
Not without modifying the source code. If you don't mind a recompile, then take a look at QSignalSpy, but one process can not monitor another processes signals, and those signals are are processed internally.

tbscope
4th October 2010, 18:33
Is this something you want?
http://sourceforge.net/projects/conanforqt/

mlheese
4th October 2010, 18:34
Thanks for the response!

What about through QProcess or another Qt Class? I could work with the connect() function but would need to find a way to get a pointer to the running app?

Is it possible to get some kind of QObject (or other) pointer to a running Qt app, say, if it was launched using QProcess??

for example, are there any methods through QProcess (or other class) that would do:

CMyMainWindowClass::CMyMainWindowClass(){
. . .

m_myProcess = new QProcess(this);
m_myProcess->start("myoldQtapp.exe", arguments);

QObject *obj = m_myProcess->GetQtObjectPointerToApp(); //how could I get the running app's QObject or QMainWindow pointer for connecting Slots to??

connect(obj, SIGNAL(oldappsignal()), this, SLOT(OnOldAppSignal()));
}

tbscope
4th October 2010, 18:37
If you dynamically link your program, you can easilly inject another library that overrides some functions and thus you gain complete access to your program from an "external" source.

Edit: how this is done on Windows, I don't know. On linux you use LD_PRELOAD to load your custom library first.

And, the work this takes, I guess you can also put it directly in your program without resulting to hacks.

squidge
4th October 2010, 19:23
Thanks for the response! What about through QProcess or another Qt Class?Each process uses a different memory space, so one process can not access another processes memory directly. They have to access it through API calls such as ReadProcessMemory and WriteProcessMemory, which would be far too slow for your requirement.

You could inject a DLL into the process at run time, or replace a DLL if your apps are dynamically linked (as suggested by tbscope) but the time taken to do that would be more than it would take to just recompile the program with modifications, and recompiling would be far more reliable.

wysota
5th October 2010, 06:04
If you dynamically link your program, you can easilly inject another library that overrides some functions and thus you gain complete access to your program from an "external" source.

Edit: how this is done on Windows, I don't know. On linux you use LD_PRELOAD to load your custom library first.

You can always craft a custom QtCore library which will dump something to the console every time QObject::connect() and QMetaObject::metacall() are called. You can even make it read some configuration from an external source to dump only those things you are interested in.