📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の11版が非表示)
147行目: 147行目:
<br>
<br>
* QByteArray localMachineId()
* QByteArray localMachineId()
*: D-Busシステムが知っているローカルIDを返します。
*: D-Busシステムが知っているローカルIDを返す。
<br>
<br>
* QDBusConnection sender()
* QDBusConnection sender()
264行目: 264行目:
* <code>-p <アダプターソースコードのファイル名></code> または <code>-P <アダプターソースコードのファイル名></code>
* <code>-p <アダプターソースコードのファイル名></code> または <code>-P <アダプターソースコードのファイル名></code>
*: アダプターソースコードのファイルへのプロキシコードを生成する。
*: アダプターソースコードのファイルへのプロキシコードを生成する。
<br><br>
== Qtプロジェクト (.pro) / CMakeLists.txt ==
* Qtプロジェクト (.pro) を使用する場合
<syntaxhighlight lang="make">
QT += dbus
</syntaxhighlight>
<br>
<br>
* CMakeLists.txtを使用する場合
<syntaxhighlight lang="cmake">
# QtDBusライブラリの検索 (Qt6を検索して、無ければQt5を使用)
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS DBus)
# QtDBusライブラリを検索
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS DBus)
# QtDBusライブラリとのリンク
target_link_libraries(<ターゲット名> PRIVATE
    Qt${QT_VERSION_MAJOR}::DBus
)
</syntaxhighlight>
<br><br>


==== サンプルコード ====
== 使用例 ==
==== pingの送受信 ====
以下の例では、Qtにおいて、D-Busを使用したメッセージの送受信を行っている。<br>
以下の例では、Qtにおいて、D-Busを使用したメッセージの送受信を行っている。<br>
# セッションバスへの接続を取得する。
# セッションバスへの接続を取得する。
334行目: 356行目:
サンプルコードの詳細を知りたい場合は、以下に示すGithubを参照すること。<br>
サンプルコードの詳細を知りたい場合は、以下に示すGithubを参照すること。<br>
https://github.com/PacktPublishing/Hands-On-Embedded-Programming-with-Qt/blob/master/Chapter10/DBusBruteForce/MyObject.cpp<br>
https://github.com/PacktPublishing/Hands-On-Embedded-Programming-with-Qt/blob/master/Chapter10/DBusBruteForce/MyObject.cpp<br>
<br>
==== Firewalldの利用 ====
以下の例では、Firewalldにおいて、以下に示すようなコマンドと同等のものをD-Busを使用して実行している。<br>
sudo firewall-cmd --permanent --zone=<ゾーン名> --add-port=<ポート番号>/tcp
sudo firewall-cmd --reload
<br>
以下に示すサンプルコードを実行するには、適切な権限 (root権限) が必要となることに注意する。<br>
<syntaxhighlight lang="c++">
#include <QDBusConnection>
#include <QDBusInterface>
#include <QDBusReply>
// 開放するポートを指定する。
bool addPort(QDBusInterface &interface, const QString &zone, QString &port, const QString &protocol)
{
    QDBusReply<void> reply = interface.call("addPort", zone, port, protocol, 0);
    return reply.isValid();
}
// 変更を永続化する
bool makePermament(QDBusInterface &interface)
{
    QDBusReply<void> reply = interface.call("runtimeToPermanent");
    return reply.isValid();
}
// Firewalldを再読み込みする
bool reloadFirewall(QDBusInterface &interface)
{
    QDBusReply<void> reply = interface.call("reload");
    return reply.isValid();
}
int main()
{
    // ...略
    // Firewalldの (ポート開放向け) D-Busインターフェースに接続する
    QDBusConnection bus = QDBusConnection::systemBus();
    QDBusInterface interface("org.fedoraproject.FirewallD1",
                            "/org/fedoraproject/FirewallD1",
                            "org.fedoraproject.FirewallD1.zone",
                            bus);
    // 複数のゾーンに対して操作を行うことも可能
    QStringList zones = {"public", "internal", "work"};
    for (const auto& zone : zones) {
      if (addPort(interface, zone, "80", "tcp")) {
          qDebug() << "Port 80 added to" << zone << "zone successfully";
      }
      else {
          qDebug() << "Failed to add port 80 to" << zone << "zone";
          return -1;
      }
    }
    // 変更を恒久的に設定する
    QDBusInterface ifReload("org.fedoraproject.FirewallD1",
                            "/org/fedoraproject/FirewallD1",
                            "org.fedoraproject.FirewallD1",
                            bus);
    if (makePermament(ifReload)) {
      qDebug() << "Changes made permanent";
      return -1;
    }
    if (reloadFirewall(ifReload)) {
      qDebug() << "Firewall reloaded";
      return -1;
    }
    // ...略
    return 0;
}
</syntaxhighlight>
<br>
==== 構造体の送信 ====
以下の例では、D-Busを使用して構造体を送信している。<br>
<syntaxhighlight lang="c++">
// DBusSender.hファイル
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDebug>
struct Hoge {
    QString    str;
    QStringList list;
    int        integer;
    double      fpoint;
};
// D-Bus向けマーシャリング関数
QDBusArgument &operator<<(QDBusArgument &argument, const Hoge &hoge)
{
    argument.beginStructure();
    argument << hoge.str << hoge.list << hoge.integer << hoge.fpoint;
    argument.endStructure();
    return argument;
}
// D-Bus向けマーシャリング関数
const QDBusArgument &operator>>(const QDBusArgument &argument, Hoge &hoge)
{
    argument.beginStructure();
    argument >> hoge.str >> hoge.list >> hoge.integer >> hoge.fpoint;
    argument.endStructure();
    return argument;
}
class DBusSender : public QObject
{
    Q_OBJECT
public:
    DBusSender(QObject *parent = nullptr) : QObject(parent) {}
    void sendStructure(const Hoge &hoge) {
      QDBusMessage message = QDBusMessage::createMethodCall(
            "org.example.hoge",  // D-Busサービス名
            "/org/example/hoge",  // D-Busオブジェクト名
            "org.example.hoge",  // D-Busインターフェース名
            "sendstructure"      // D-Busインターフェースメソッド名
      );
      QVariant variant;
      variant.setValue(hoge);
      message << variant;
      QDBusConnection::sessionBus().send(message);
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include "DBusSender.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // 送信する構造体の型をD-Busシステムに登録
    qDBusRegisterMetaType<Hoge>();
    DBusSender sender;
    // 送信データの作成
    Hoge hoge;
    hoge.str    = "Hello, D-Bus!";
    hoge.list    = QStringList{"item1", "item2", "item3"};
    hoge.integer = 100;
    hoge.fpoint  = 3.14f;
    // データを送信
    sender.sendStructure(hoge);
    qDebug() << "Structure sent via D-Bus";
    return a.exec();
}
</syntaxhighlight>
<br>
<code>qDBusRegisterMetaType<構造体>()</code>は、QtのD-Busシステムに対して、カスタム型を登録するための関数呼び出しである。<br>
これは、カスタム型をD-Bus経由で送信する際に必須の操作である。<br>
<br>
* 型の登録
*: この関数は、QtのD-Busシステムに構造体を<u>知らせる</u>ためのものである。
*: D-Busは標準的なデータ型 (整数、文字列等) を扱うことができるが、カスタム型については明示的に登録する必要がある。
*: <br>
* シリアライズとデシリアライズ
*: この登録により、Qtはカスタム型をどのようにシリアライズ (バイトストリームに変換) して、デシリアライズ (バイトストリームから元の型に戻す) すべきかを理解する。
*: これは、D-Busを通じてデータを送受信する時に必要となる。
*: <br>
* マーシャリング関数の使用
*: 登録プロセスは、<code>operator<<</code>と<code>operator>></code>関数を使用する。
*: これらの関数が、カスタム型のマーシャリング (データの変換) 方法を定義している。
*: <br>
* 型の安全性
*: この登録により、D-Bus経由でカスタム型のオブジェクトを安全に送受信できるようになる。
*: Qtは、送信時にこの型をシリアライズして、受信時に正しくデシリアライズすることができる。
*: <br>
* メタオブジェクトシステムとの統合
*: この関数呼び出しは、カスタム型をQtのメタオブジェクトシステムに統合する。
*: これにより、Qtの様々な機能 (シグナル/スロットシステム等) でカスタム型が使用できるようになる。
*: <br>
* 実行時の型情報
*: この登録により、D-Busシステムは実行時にカスタム型の情報を持つことができ、適切なデータ変換を行うことができる。
<br>
したがって、<code>qDBusRegisterMetaType<カスタム型></code>関数を呼び出すことにより、カスタム型をD-Busシステムで使用可能にして、データを送受信できるようにしている。<br>
<br>
==== 構造体の受信 ====
<syntaxhighlight lang="c++">
// DBusReceiver.hファイル
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
#include <QDBusError>
#include <QDebug>
struct Hoge {
    QString str;
    QStringList list;
    int integer;
    double fpoint;
};
Q_DECLARE_METATYPE(Hoge)
// D-Bus向けマーシャリング関数
QDBusArgument &operator<<(QDBusArgument &argument, const Hoge &hoge) {
    argument.beginStructure();
    argument << hoge.str << hoge.list << hoge.integer << hoge.fpoint;
    argument.endStructure();
    return argument;
}
// D-Bus向けマーシャリング関数
const QDBusArgument &operator>>(const QDBusArgument &argument, Hoge &hoge) {
    argument.beginStructure();
    argument >> hoge.str >> hoge.list >> hoge.integer >> hoge.fpoint;
    argument.endStructure();
    return argument;
}
class DBusReceiver : public QObject {
    Q_OBJECT
    // Q_CLASSINFOマクロを使用して、D-Busインターフェース名を指定
    Q_CLASSINFO("D-Bus Interface", "org.example.hoge")
public:
    DBusReceiver(QObject *parent = nullptr) : QObject(parent) {}
public slots:
    bool sendstructure(const Hoge &hoge)
    {
      try {
          qDebug() << "受信した構造体:";
          qDebug() << "str: " << hoge.str;
          qDebug() << "list: " << hoge.list;
          qDebug() << "integer: " << hoge.integer;
          qDebug() << "fpoint: " << hoge.fpoint;
          return true;
      }
      catch (const std::exception &e) {
          qCritical() << "Error processing received structure: " << e.what();
          return false;
      }
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include "DBusReceiver.h"
bool setupDBusConnection(DBusReceiver &receiver)
{
    QDBusConnection connection = QDBusConnection::sessionBus();
    if (!connection.isConnected()) {
        qCritical() << "Cannot connect to the D-Bus session bus:" << connection.lastError().message();
        return false;
    }
    if (!connection.registerService("org.example.hoge")) {
        qCritical() << "Failed to register service:" << connection.lastError().message();
        return false;
    }
    if (!connection.registerObject("/org/example/hoge", &receiver, QDBusConnection::ExportAllSlots)) {
        qCritical() << "Failed to register object:" << connection.lastError().message();
        return false;
    }
    return true;
}
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    // カスタム型をD-Busシステムに登録
    qRegisterMetaType<Hoge>("Hoge");
    qDBusRegisterMetaType<Hoge>();
    DBusReceiver receiver;
    if (!setupDBusConnection(receiver)) {
        return -1;
    }
    qDebug() << "D-Bus server is running. Waiting for incoming messages...";
    return a.exec();
}
</syntaxhighlight>
<br>
<code>Q_DECLARE_METATYPE(カスタム型)</code>は、Qtのメタオブジェクトシステムにカスタム型を登録するためのマクロである。<br>
<br>
* 型の登録
*: この宣言により、カスタム型がQtのメタオブジェクトシステムに認識される。
*: これにより、Qtの様々な機能 (シグナル/スロットシステム、プロパティシステム等) でカスタム型を使用できるようになる。
*: <br>
* QVariantとの互換性
*: カスタム型をQVariantオブジェクトに格納、および、QVariant型から取り出すことが可能になる。
*: <br>
* シリアライゼーション
*: Qtの機能を使用してカスタム型のオブジェクトをシリアライズ (バイナリデータに変換)、デシリアライズ (バイナリデータから元のオブジェクトに戻す) することができるようになる。
*: <br>
* 型の安全性
*: コンパイル時の型チェックが可能になり、カスタム型を使用する時の型の安全性が向上する。
*: <br>
* qRegisterMetaTypeとの連携
*: <code>Q_DECLARE_METATYPE</code>と<code>qRegisterMetaType</code>を併用することにより、
*: Qtのスレッド間通信やイベントシステムでもカスタム型を安全に使用できるようになる。
*: <br>
* D-Busとの連携
*: D-Busシステムでカスタム型を使用する場合、この宣言により型情報が適切に処理される。
*: <br>
* 動的プロパティ
*: Qtの動的プロパティシステムでカスタム型を使用することが可能になる。
<br>
具体的な使用例を以下に示す。<br>
<syntaxhighlight lang="c++">
// シグナル / スロットでの使用
signals:
    void hogeChanged(const Hoge &newHoge);
// QVariant型での使用
Hoge myHoge;
QVariant variant = QVariant::fromValue(myHoge);
// D-Busでの使用
QDBusMessage message;
message << QVariant::fromValue(myHoge);
</syntaxhighlight>
<br>
<u>※注意</u><br>
<u><code>Q_DECLARE_METATYPE</code>はヘッダファイル内で使用して、</u><br>
<u>対応する<code>qRegisterMetaType</code>関数呼び出しは、一般的に、<code>main</code>関数内や型を使用する前に1度だけ行う必要がある。</u><br>
<br>
<u>このマクロを使用することにより、カスタム型がQtのシステムにシームレスに統合されて、D-Bus通信を含む様々なQtの機能で安全かつ効率的に使用できるようになる。</u><br>
<br><br>
<br><br>


341行目: 714行目:
  # mocファイルはインクルードしない場合
  # mocファイルはインクルードしない場合
  qdbusxml2cpp -a <生成するcppファイル名とヘッダファイル名> -c <自動生成するヘルパークラス名 (親クラス)> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
  qdbusxml2cpp -a <生成するcppファイル名とヘッダファイル名> -c <自動生成するヘルパークラス名 (親クラス)> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
  例. qdbusxml2cpp -a SamplesAdaptor -c SamplesAdaptor -i SampleHelper.h -l SampleHelper org.qt.policykit.examples.xml
  例. qdbusxml2cpp -a SamplesAdaptor -c SamplesAdaptor -i SampleHelper.h -l SampleHelper org.dbus.interface.examples.xml
   
   
  # mocファイルもインクルードする場合
  # mocファイルもインクルードする場合
  qdbusxml2cpp -m -a <生成するcppファイル名とヘッダファイル名> -c <自動生成するヘルパークラス名 (親クラス)> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
  qdbusxml2cpp -m -a <生成するcppファイル名とヘッダファイル名> -c <自動生成するヘルパークラス名 (親クラス)> -i <対象となるクラスを記述しているヘッダファイル> -l <対象となるクラス名> <D-Busインターフェースファイルのパス>
  例. qdbusxml2cpp -m -a SamplesAdaptor -c SamplesAdaptor -i SampleHelper.h -l SampleHelper org.qt.policykit.examples.xml
  例. qdbusxml2cpp -m -a SamplesAdaptor -c SamplesAdaptor -i SampleHelper.h -l SampleHelper org.dbus.interface.examples.xml
<br>
<br>
生成されたファイルをQtプロジェクトに指定およびインクルードする。<br>
生成されたファイルをQtプロジェクトに指定およびインクルードする。<br>
354行目: 727行目:


== CMakeプロジェクト ==
== CMakeプロジェクト ==
CMakeプロジェクトにおいて、<code>qt_add_dbus_adaptor</code>オプションを指定することにより、D-Busインターフェースのアダプタクラスを生成する。<br>
CMakeプロジェクトにおいて、<code>qt_add_dbus_adaptor</code>コマンドを指定することにより、D-Busインターフェースのアダプタクラスを生成することができる。<br>
<code>qt_add_dbus_adaptor</code>コマンドは、Qt D-Bus XMLコンパイラ(qdbusxml2cpp)のアダプタモードでの呼び出しを設定する。<br>
<code>qt_add_dbus_adaptor</code>コマンドは、Qt D-Bus XMLコンパイラ (qdbusxml2cpp) のアダプタモードでの呼び出しを設定する。<br>
<br>
<br>
第2引数で指定したD-Busインタフェースファイル(XML形式)に対するアダプタを実装したC++のソースコードファイルとヘッダファイルを生成する。<br>
第2引数で指定したD-Busインタフェースファイル(XML形式)に対するアダプタを実装したC++のソースコードファイルとヘッダファイルを生成する。<br>
368行目: 741行目:
<br>
<br>
第4引数から第6引数までを省略する場合、親クラス名、ヘッダファイル名、クラス名は、第3引数の指定値から自動的に生成される。<br>
第4引数から第6引数までを省略する場合、親クラス名、ヘッダファイル名、クラス名は、第3引数の指定値から自動的に生成される。<br>
<syntaxhighlight lang="cmake">
<syntaxhighlight lang="cmake">
  qt_add_dbus_adaptor(
  qt_add_dbus_adaptor(
   <任意の変数名>            # 生成されるソースファイル名を指定  例: SampleAdaptor.cpp  SampleAdaptor.h
   <任意の変数名>            # 生成されるソースファイル名を指定  例: SampleAdaptor.cpp  SampleAdaptor.h
380行目: 753行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>
{{#seo:
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|image=/resources/assets/MochiuLogo_Single_Blue.png
}}


__FORCETOC__
__FORCETOC__
[[カテゴリ:Qt]]
[[カテゴリ:Qt]]