2016-09-28 5 views
1

問題の概要:qdbusxml2cppは方法D-Busは非同期返信フェッチQDBusAbstractInterfaceサブクラスを生成し、私は(応答が受信されるまで、すなわち、それはブロックする)、それは、同期したいです。qdbusxml2cppで同期インタフェースクラスを生成する方法は?

XML入力:このコマンドヘッダ(図示せず).cppファイルで

<?xml version="1.0"?> 
<!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="some.interface.Foo"> 
    <method name="GetValues"> 
    <arg name="values" type="a(oa{sv})" direction="out"/> 
     <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QList&lt;SomeStruct&gt;" /> 
    </method> 
</interface> 
</node> 

が生成される:

qdbusxml2cpp-qt5 -c InterfaceFoo -p interface_foo foo.xml 

生成ヘッダ:あなたと

class InterfaceFoo: public QDBusAbstractInterface 
{ 
    Q_OBJECT 
public: 
    static inline const char *staticInterfaceName() 
    { return "some.interface.Foo"; } 

public: 
    InterfaceFoo(const QString &service, const QString &path, const QDBusConnection &connection, QObject *parent = 0); 

    ~InterfaceFoo(); 

public Q_SLOTS: // METHODS 
    inline QDBusPendingReply<QList<SomeStruct> > GetValues() 
    { 
     QList<QVariant> argumentList; 
     // NOTICE THIS LINE. 
     return asyncCallWithArgumentList(QStringLiteral("GetValues"), argumentList); 
    } 

Q_SIGNALS: // SIGNALS 
}; 

namespace some { 
namespace interface { 
    typedef ::InterfaceFoo Foo; 
} 
} 
#endif 

生成されたメソッドを見ることができますasyncCallWithArgumentList()は非同期です:それはconnect() Dバス応答が到着したときにトリガーされるスロットに接続される。

代わりに私が行うことができるようにしたい:

some::interface::Foo *interface = new some::interface::Foo("some::interface", "/Foo", QDBusConnection::systemBus(), this); 
// THIS SHOULD block until a reply is received or it times out. 
QList<SomeStruct> data = interface->GetValues(); 
+1

あなたが探している解決策ではありませんが、返信が到着するまで 'interface-> GetValues()。value()'を呼び出すことができます –

答えて

1

あなたに-あるGetValues()と、ブロックするように戻り値にvalue()を使用することもできます。

auto reply = interface->GetValues(); 
auto data = reply.value<QList<QVariant>>(); 

ああ、生成されたインターフェースがあります一度生成されてからあなたのソースの一部になることを意味します。あなたはブロッキング呼び出しを使用するように変更し、バリアントからの具体的な型に変換を追加する必要があります。最後に

inline QDBusPendingReply<QList<SomeStruct>> GetValues() 
{ 
    QList<QVariant> argumentList; 
    auto msg = callWithArgumentList(QDBus::Block, QStringLiteral("GetValues"), argumentList); 
    Q_ASSERT(msg.type() == QDBusMessage::ReplyMessage); 
    QList<SomeStruct> result; 
    for (auto const & arg : msg.arguments()) 
     result << arg.value<SomeStruct>(); 
    return result; 
} 

、あなたはそれが同期すること再考したいかもしれません:現実の世界では、非同期である、ようにコードを書きますそうでない場合はしばしば非生産的です。あなたのコードがメインスレッドで実行されていてGUIがある場合、悪いユーザーエクスペリエンスを与えるでしょう。あなたのコードをワーカースレッドに移すと、同期コーディングスタイルをサポートするためだけにスレッド全体が無駄になります。非インタラクティブなバッチスタイルのユーティリティ/サービスに相当するものを書いているとしても、潜在的に待ち時間は例えば5分で増加します。並行してコールを発行しません。

+0

答えと最後の段落のアドバイスに感謝します。それは助けになった! – DBedrenko

+0

生成されたソース/ヘッダーファイルの先頭に「これは自動生成されたファイルです。編集しないでください!変更はすべて失われます。それは変更されないように聞こえますが、teh .xmlはマスターファイルです... – DBedrenko

+0

@Deeそれはあなたの宇宙です、あなたはそのマスターです、あなたはルールを設定します。あなたはツールを使用します。それは神からの贈り物ではありません。 –

関連する問題