1

皆さん、こんにちは。

これは長い質問になるでしょう。必要でない場合は [背景] を飛ばしてください ;)

【背景

モジュラー QT ベースのアプリケーションを開発しています。アプリケーションは、QT ベースのプラグインを介して拡張可能です。図のように、主に3つのパーツがあります(赤数字)。

代替テキスト

1) libAppCore - アプリケーションのコアであり、プラグイン インターフェイス、メイン UIS、相互接続などを定義します。

2) App.exe - いくつかの組み込みプラグインとメイン アプリケーションの実行を実装するアプリケーション。

3) Qt ベースのプラグイン- プラグイン インターフェイスを実装するいくつかのプラグインlibAppCore.dll

各コンポーネントが相互にリンクする方法は次のとおりです。

  • libAppCore は QT ライブラリをリンクします。

  • App.exe は、libAppCore.DLL と QT ライブラリをリンクします (App.exe は、私の libAppCore.DLL が使用されていない別の QT クラスを使用します)。

  • プラグイン ( libAppQTPluginA.DLL 、 libAppQTPluginB.DLL ) - libAppCore.DLL と QT ライブラリをリンクします。libAppQTPluginA.DLL - OpenGL へのリンク libAppQTPluginB.DLL - VTK ライブラリへのリンク

【実際の問題】] ここでも Windows でのみ発生しますが、Linux では問題なく動作します。

すべてが正常にコンパイルされ、VTK ライブラリを使用する PluginB の実行時にのみ問題が発生します。

PluginB の実行中に、QMainWindow の中央ウィジェットとして設定される QWidget を作成します (一度に多くの QMainWindow が存在する可能性があります)。

QVTKWidget qtWidget = 新しい QVTKWidget(this); qtWidget->resize(512, 512);

vtkSmartPointer sphereSource = vtkSmartPointer::New(); sphereSource->Update(); vtkSmartPointer sphereMapper = vtkSmartPointer::New(); sphereMapper->SetInputConnection(sphereSource->GetOutputPort()); vtkSmartPointer sphereActor = vtkSmartPointer::New(); sphereActor->SetMapper(sphereMapper);

// VTK レンダラー vtkSmartPointer leftRenderer =vtkSmartPointer::New(); leftRenderer->AddActor(sphereActor);

qtWidget->GetRenderWindow()->AddRenderer(leftRenderer); QVBoxLayout *vboxLayout = 新しい QVBoxLayout; vboxLayout->addWidget(qtWidget); setLayout(vboxLayout);

実行中、QT は複数のスレッドについて警告しますが、新しいスレッドや VTK (AFAIK) を作成することはありません。

QObject: Cannot create children for a parent that is in a different thread.(Parent is QObject(0xdbe0d70), parent's thread is QThread(0x3370f8), current thread is QThread(0xdc427f8)

(しかし、行 vboxLayout->addWidget(qtWidget); をコメントアウトすると、これは消えます。)

また、QVTKWidget で何らかの操作を実行すると、アプリケーションがクラッシュします。エラー ログは

> Program received signal SIGSEGV,
> Segmentation fault. 0x01024c41 in
> QRegion::isEmpty (this=0x28d480) at
> painting\qregion.cpp:3975 3975   
> painting\qregion.cpp: No such file or
> directory.
>         in painting\qregion.cpp (gdb) back
> #0  0x01024c41 in QRegion::isEmpty (this=0x28d480)
>     at painting\qregion.cpp:3975
> #1  0x00f0f18a in QWidgetPrivate::childAt_helper
> (this=0xf3957a0, p=...,
>     ignoreChildrenInDestructor=false) at kernel\qwidget.cpp:9641
> #2  0x00f0f109 in QWidgetPrivate::childAt_helper
> (this=0xb3c8218, p=...,
>     ignoreChildrenInDestructor=false) at kernel\qwidget.cpp:9636
> #3  0x00f0ef9e in QWidget::childAt (this=0x3be0b0, p=...)
>     at kernel\qwidget.cpp:9600
> #4  0x00f27bb6 in QETWidget::translateMouseEvent
> (this=0xf3701e8, msg=...)
>     at kernel\qapplication_win.cpp:3114
> #5  0x00f234db in QtWndProc@16 (hwnd=0x70af4, message=513, wParam=1,
>     lParam=14090539) at kernel\qapplication_win.cpp:1629
> #6  0x767a6238 in USER32!IsDialogMessageW ()    from
> C:\Windows\syswow64\user32.dll
> #7  0x00070af4 in ?? () warning: (Internal error: pc 0x200 in read in
> psymtab, but not in symtab.)
> 
> warning: (Internal error: pc 0x200 in
> read in psymtab, but not in symtab.)
> 
> #8  0x00000201 in ?? (warning: (Internal error: pc 0x200 in read in
> psymtab, but  not in symtab.)

任意のヒント ?最初に複数のスレッドについて比較するのはなぜですか?

4

1 に答える 1

0

最後に解決策を見つけました.リリースバージョン用にVTKライブラリをコンパイルしましたが、他のすべてのコンポーネントはデバッグバージョンをビルドしました。2 つの QT ライブラリがリンクされているため (リリース バージョンとデバッグ バージョン)、QT はバージョンごとに 2 つのスレッドを作成します。最後に、Release ビルド オプションを使用してすべてをビルドすると、すべて正常に動作します。

于 2010-09-10T05:22:31.647 に答える