Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Cannot marshal std::string with QDbus



  • I'm trying to add dbus functionality to an existing class and see this from qdbuscpp2xml: Unregistered input type in parameter list: std::string.

    qdbuscpp2xml -A include/foobar.h -o org.foo.bar.xml
    

    My class looks like this:

    class FooBar: public QObject
    {
      Q_OBJECT
      Q_CLASSINFO("foo bar", "org.foo.bar")
    
    public Q_SLOTS:
      std::vector<std::string> getAvailableActions() const;
      std::vector<std::string> getActions(const std::string& state_name) const;
      bool isBusy() const;
      bool wait(double timeout) const;
    
    Q_SIGNALS:
      void enter(std::string);
      void exited(std::string);
    

    And the following XML is generated:

    <!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
    <node>
      <interface name="local.FooBar">
        <method name="isBusy">
          <arg type="b" direction="out"/>
        </method>
        <method name="wait">
          <arg type="b" direction="out"/>
          <arg name="timeout" type="d" direction="in"/>
        </method>
      </interface>
    </node>
    

    Questions:

    1. Why is it having a problem with std::string?
    2. Is the problem with std:string the reason for missing methods and signals in the XML?
    3. Why is the interface name local.FooBar and not org.foo.bar (as I expect)?
    4. BONUS Question: Why does qt5_generate_dbus_interface not generate the XML?
    qt5_generate_dbus_interface(
        include/foobar.h
        org.foo.bar.xml
        OPTIONS -A
    )
    

    Any help appreciated!


  • Lifetime Qt Champion

    Hi,

    I haven't used that module yet but what if you using QString and QStringList in place std::string and std::vectorstd::string ?

    By the way, usually slots have no return value. Methods that should return values and be usable by the meta object system are marked with Q_INVOKABLE.

    Getters are not slots.



  • As I mentioned, it's an existing class, so changing is not the best option. My preference is to make work as is and I don't want to (shouldn't need to) make changes or have some wrapper.

    I found a number of examples/tutorials (e.g. this one) that show slots with return values, and none of these require Q_INVOKABLE. My understanding is that Q_INVOKABLE is for QML, which I'm not interested in at the moment (however that may come along at some point).

    Also, returning something from a method call seems to be rather well defined.

    Maybe you could look into when you have a chance, and/or pull in some other resources if need be?


  • Lifetime Qt Champion

    @wpmccormick said in qdbuscpp2xml: Unregistered input type in parameter list:

    I found a number of examples/tutorials (e.g. this one) that show slots with return values, and none of these require Q_INVOKABLE.

    As I wrote: usually they don't have return values. I didn't wrote slots required Q_INVOKABLE when they have return values.

    Q_INVOKABLE is used by QML but its existence predates QML by a very long time.

    As for your type problem, did you already read the The Qt D-Bus Type System chapter in Qt's documentation ?



  • Yes, I looked at that early on, but it was worth taking another look. From that, it appears that std::string is not supported, even though (from other docs/examples/tutorials) std::vector, std::list, and other like container types are supported. Still, it's such a well used type, I can't help but wonder if there still isn't someway to do it. Is there someone you might be able to ask?

    Also, direct copy/paste quote, you wrote "Methods that should return values and be usable by the meta object system are marked with Q_INVOKABLE."

    To me, that seems to imply that it's required, but I appreciate the confirmation that it is not.



  • If you are supporting existing calls that use those methods you can always add more methods:

      std::vector<std::string> getAvailableActions() const;
      std::vector<QString> getAvailableActions() const;
      std::vector<std::string> getActions(const std::string& state_name) const;
      std::vector<QString> getActions(const QString& state_name) const;
    

    Just have those new methods call the std::string versions. Yes it will be slower, but it maintains the old interface to talks to the new.



  • It's not a bad option, but still, std::string is as close as you can get to being a primitive data type, without being a primitive data type. Somehow QtDbus seem a little broken without it.


  • Lifetime Qt Champion

    Just to clear something out: you can use std::string for your arguments however this will require some manual work. qdbus2xml is just a tool to help create the xml definitions. It was written with Qt in mind (since you are using the QDbus module) but currently does not support generating xml for custom types. However it doesn't mean that you can't use them. You should not put that tool and the module capabilities in the same bag.

    Have a look at this very interesting KDE tutorial about DBus and custom types.



  • So that link is pretty much what I noted earlier in thread (part of the same tutorial) ... so yes, I've already been through that, and there's nothing there that I can see that will make std::string work. Unless there is some way to make std::string work, then I think the @fcarney solution is not a bad work-around; but it doesn't resolve the issue.

    My point on centering the discussion on the qdbuscpp2xml tool is that if it will not generate the XML for the interface that I need, then moving forward with cmake tools for generating the interface will be problematic as well.

    I think I should rename this topic to Cannot marshal std::string with QDbus.



  • @fcarney now the issue is that qdbuscpp2xml doesn't generate an interface (XML) for the methods that return std:vector<QString>. I also tried QList<Qstring> and that doesn't work either.

    I threw in a

    Q_DECLARE_METATYPE(QList<QString>);
    

    just for good measure, and still nothing.


  • Lifetime Qt Champion

    Use QStringList



  • @wpmccormick
    I will answer your 3rd question,you should write Q_CLASSINFO("D-Bus Interface", "org.foo.bar"),your interface name can be correct.
    Now,I have a new question Unregistered input type in parameter list: ServiceStatusList when I use qdbuscpp2xml to generate xml.
    Who can tell me what should I do,thanks a lot.


Log in to reply