2

Qt を使用しない libcommuni を、Qt を使用しない別の DLL プロジェクトにラップしています。私が知る限り、QCoreApplicationネットワーキングやシグナルなどが適切に機能することを確認するには、Qt メッセージ ポンプを (経由で) 実行する必要があります。ただし、それを行う方法を理解するためにいくつかの問題に直面しています。

QCoreApplication::exec()基本的に、すべての Qt イベントを呼び出してポンプする DLL でスレッドをスピンアップしたいと考えています。次に、別のスレッドにある DLL への外部呼び出しを Qt メイン スレッドにマーシャリングして、libcommuni を安全に使用できるようにします。

これにはシグナルとスロットを使用することが推奨されるアプローチのようですが、私はそれを機能させることができませんでした。QObjectDLL 経由で呼び出されるクラスでシグナルを作成し、それをQThreadQt メッセージ ポンプを実行する のスロットに接続します。ただし、Qt::QueuedConnectionシグナルとスロットを接続するときに指定すると、シグナルを送信してもメッセージが配信されません。完全に省略した場合Qt::QueuedConnection、スロットは Qt のメイン スレッドではなく、呼び出し元のスレッドですぐに呼び出されます。

また、DLL スレッドで明示的に呼び出しQCoreApplication::postEvent()てイベントを Qt メイン スレッドに送信しようevent(QEvent)としましたが、 target で呼び出されることはありませんQThread

ここで私が間違っていることについてのアイデアはありますか? Qt のスレッド モデルをよく理解していないと思います。

4

1 に答える 1

1

QObject::connect接続タイプを指定せずに使用すると、信号とスロットが単一のスレッドにある場合は にQt::AutoConnection変わり、異なるスレッドにある場合は に変わります。したがって、あなたの場合、差し当たり、信号をスロットに接続すると、それらが属するオブジェクトは 1 つのスレッドに配置されると言えます。Qt::DirectConnectionQt::QueuedConnection

機能させるにQt::QueuedConnectionは、スロットを含むスレッドにイベント ループが必要です。

QThread を使用する主な方法は 2 つあります。

  1. を導出QThreadして書き換えることができますQThread::run。その場合、いくつかのことを行う必要があります。

    • スレッドのオブジェクトを作成するときは、親を指定しないでください。このオブジェクトを手動で削除してください。
    • スレッドのコンストラクター呼び出しでmoveToThread(this).
    • スレッドのrunメソッドで、すべての初期化の後、すべての削除の前に exec を呼び出します。execを呼び出した直後にスレッドが終了しますQThread::quit
  2. を呼び出す前に、オブジェクトを派生させ、オブジェクトQObjectを作成し、QThreadオブジェクトを呼び出すことができQThread::moveToThreadます (ちなみに、親を指定せずに作成する必要があります) QThread::start

あなたの場合、2番目の方法を使用することをお勧めします。

それはスレッドに関するものですが、よくわかりません。あなたの問題はQCoreApplication::exec.

于 2013-04-07T05:16:54.823 に答える