PDA

View Full Version : QVariant, QtDBus, pointers & custom classes



zuck
23rd September 2009, 15:39
Hi, I need to send a pointer to a custom class (a model derived from QSqlRelationalTableModel) over the DBus. What I already know:

- I can incapsulate an arbitrary object into a QVariant instance.
- I can incapsulate a pointer to an arbitrary object into a QVariant instance.
- I can save and restore this object if I implement << and >> operators (with QDataStream argument).
- I can incapsulate a QVariant into a QDBusVariant if I need to send it over the DBus.
- I can send an arbitrary object over the DBus if I implement << and >> operators (with QDBusArgument argument).

So, how can I do this?

My idea is:

1) Add Q_DECLARE_METATYPE(MyClass) and Q_DECLARE_METATYPE(MyClass*) at the end of MyClass declaration.
2) Implement QDataStream &operator<<(QDataStream &out, const MyClass &myObj) and QDataStream &operator>>(QDataStream &in, MyClass &myObj) operators.
3) Implement QDBusArgument &operator<<(QDBusArgument &out, const MyClass &myObj) and QDBusArgument &operator>>(QDBusArgument &in, MyClass &myObj) operators.
4) Implement MyClass(), MyClass(const MyClass& obj), ~MyClass() c/dtors.
5) Add qDBusRegisterMetaType<MyClass>() call into all ctors.

With these steps, can I write something like this (if we suppose remote and local objects are in the same process)?



// Remote object
class MyQDBusAdaptor
{
// ...
MyClass* my_method();
}

// Local object
QDBusInterface app("...", "...", "...");
MyClass* ret = app->call("my_method");

zuck
28th September 2009, 12:01
Up! :p I think this is a interesting duscussion topic...

wysota
28th September 2009, 12:25
Hi, I need to send a pointer to a custom class (a model derived from QSqlRelationalTableModel) over the DBus.
Forget it, you can't pass pointers between processes as each process has its own memory space. The same address can point to two different places in physical memory in different processes.

zuck
28th September 2009, 15:23
Forget it, you can't pass pointers between processes as each process has its own memory space. The same address can point to two different places in physical memory in different processes.

Yes, I know. In fact this is the point: how can I pass a complex object over the DBUS?

In my specific case I can pass only the SQL driver name, the database name, the connection name and the table name and then construct the class instance with this data, but if I can't send a pointer I can't send, for example, a QWidget instance or similar...is it correct?

I ask for this because I want to centralize in a service plugin the access to a specific model class from all the user plugins of my framework (they run in the same process). In the user plugin code there are the views and in the service plugin code there is the model access management. Now I want to connect the views with the model over the DBus (each plugin is decoupled with the rest of the framework).

wysota
28th September 2009, 15:31
You can't transfer any complex object between processes directly. You have to serialize the object, transfer it as a series of bytes and then recreate the object from those bytes in the other process.

zuck
1st October 2009, 12:54
Do you think using QSharedMemory could be a good solution for this?

wysota
1st October 2009, 13:03
Could be but still you can't just place the object in shared memory in one process and take it from there in the other one. You have to operate on a per-byte level and reconstruct the object properly (starting from calling its constructor) on the other side.

zuck
1st October 2009, 15:11
Ok, thank you!