Let DCOP Tell You the Signature
A DCOP call failed today even though the method name was correct. The method name, unfortunately, was only part of the name that mattered. I had sent an int; the exported function expected an unsigned value.
Before changing code, I ask the running object what it exposes:
dcop myapp MainIface
The output includes complete function signatures. In this case it shows void setPage(unsigned int). I then call it from the command line with a small test argument:
dcop myapp MainIface setPage 3
DCOP identifies methods by their signatures and marshals known Qt types through QDataStream. The sending and receiving sides must therefore agree on argument types, order, and return type. A visually similar C++ declaration is not necessarily the same wire contract.
For custom values, both programs need compatible streaming operators and type registration. I avoid custom structures in small public interfaces when a QString, QCString, or simple list expresses the operation clearly. Fewer private types also make the command-line client useful.
When writing the C++ caller, I keep the request and reply types visible next to each other:
QByteArray data;
QDataStream args(data, IO_WriteOnly);
unsigned int page = 3;
args << page;
QCString replyType;
QByteArray replyData;
if (!client->call(app, "MainIface", "setPage(unsigned int)",
data, replyType, replyData)) {
kdWarning() << "DCOP setPage call failed" << endl;
}
For a function with a return value, I verify replyType before extracting from replyData. Deserializing a reply under the wrong assumption merely converts a useful interface error into strange application state.
The application and object names should not be copied from a single run if multiple instances are possible. I list registered clients and decide whether the program is meant to address one instance, every instance, or the instance owning a particular document. A suffix added to keep names unique is normal, not a DCOP server losing its arithmetic.
I also preserve failures in scripts. The command-line client returns useful status, and a shell script should check it rather than carrying on after the target application has exited. Interprocess calls cross a lifetime boundary; yesterday’s object name is not a reservation for today.
I keep the exported interface narrow and test it independently of the window. If the command works but a toolbar action does not, DCOP has been acquitted and I can inspect the connection instead.
I let dcop provide the authoritative spelling instead of copying it from memory. Memory is fast, local, and apparently not type-safe.