[choreonoid-users-ja 00142] Plugin中でViewを動的に削除する方法
植芝 俊夫
t.ueshiba @ aist.go.jp
2014年 11月 19日 (水) 07:56:18 JST
産総研の植芝と申します.最近,choreonoidをビジョンシステムのGUIプラットフォームとして
使わせて頂くようになりました.素晴らしいソフトウェアを公開していただき,ありがとう
ございます.
当方の使用環境は,ubuntu-12.04 または MacOS X 10.9.5(Marvericks) の上で,ソースからコンパイル
したchoreonoid-1.4.0 を動かしています.ユーザからの指示で複数のViewを動的に生成/削除
するPluginを書きたいと思っています.この場合,Viewを生成するためには
View* view = new View();
addView(view);
とすれば良いことはわかるのですが,生成したviewを陽に削除するにはどうすれば良いのでしょうか?
試しに
bool removed = MainWindow::instance()->removeView(view)
としてみましたが,戻り値はtrueになるもののタブからViewが消えません.強引に
delete view;
とすると,そのときは消えるものの,choreonoid本体を終了したときにsegmentation faultします.
このとき,MacOS X上では
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libCnoidBase.1.4.dylib 0x0000000105314d44 cnoid::ExtensionManager::PtrHolder<cnoid::View*>::~PtrHolder() + 36
1 libCnoidBase.1.4.dylib 0x0000000105313e91 cnoid::ExtensionManagerImpl::~ExtensionManagerImpl() + 113
2 libCnoidBase.1.4.dylib 0x0000000105313d32 cnoid::ExtensionManager::~ExtensionManager() + 34
3 libCnoidMultiviewPlugin.dylib 0x000000010fc86901 MultiviewPlugin::~MultiviewPlugin() + 65 (MultiviewPlugin.cc:9)
4 libCnoidMultiviewPlugin.dylib 0x000000010fc7f355 MultiviewPlugin::~MultiviewPlugin() + 21 (MultiviewPlugin.cc:9)
5 libCnoidMultiviewPlugin.dylib 0x000000010fc7f379 MultiviewPlugin::~MultiviewPlugin() + 25 (MultiviewPlugin.cc:9)
6 libCnoidBase.1.4.dylib 0x00000001052be7f9
というようなエラーメッセージが出ますので,スマートポインタ型であるExtensionManager::PtrHolder<View*>が
管理しているviewを勝手にdeleteしたため,スマートポインタのデストラクタが呼ばれた時に2重解放になった
のではないかと推測しています.
安全にViewを削除する方法をご教示いただければ幸いです.どうかよろしくお願いいたします.
ご参考までに,動作チェックのために書いたコードを以下に添付します.メインメニューの”表示”に”New view”と
“Close view”の2項目を追加し,前者を選択すると新たなViewを生成,後者を選択すると直近に生成
したViewを削除する(つもり)のコードです.このコードのままではメニュー操作によってViewを消すことは
できず,”#if 1”を”#if 0”とすると消すことはできるものの,choreonoid終了時にクラッシュします.
===================================
#include <cnoid/Plugin>
#include <cnoid/View>
#include <cnoid/MenuManager>
#include <cnoid/MainWindow>
#include <cnoid/MessageView>
#include <boost/bind.hpp>
#include <stack>
class MultiviewPlugin : public cnoid::Plugin
{
public:
typedef cnoid::View View;
public:
MultiviewPlugin() :Plugin("Multiview") {}
virtual bool
initialize()
{
menuManager().setPath("/View")
.addItem("New view")
->sigTriggered()
.connect(boost::bind(&MultiviewPlugin::onNew, this));
menuManager().setPath("/View")
.addItem("Close view")
->sigTriggered()
.connect(boost::bind(&MultiviewPlugin::onClose, this));
return true;
}
void
onNew()
{
View* view = new View();
view->setName("My view");
_views.push(view);
addView(view);
}
void
onClose()
{
if (_views.empty())
return;
View* view = _views.top();
_views.pop();
#if 1
using namespace cnoid;
bool removed = MainWindow::instance()->removeView(view); // viewが消えない
if (removed)
MessageView::instance()->putln("MultiviewPlugin: Removed.");
else
MessageView::instance()->putln("MultiviewPlugin: Not Removed.");
MainWindow::instance()->update();
#else
delete view; // viewは消えるが,choreonoid終了時にSEGV
#endif
}
private:
std::stack<View*> _views;
};
CNOID_IMPLEMENT_PLUGIN_ENTRY(MultiviewPlugin);
===================================
===================================================================
植芝俊夫 t.ueshiba @ aist.go.jp
産業技術総合研究所
知能システム研究部門 タスクビジョン研究グループ
Addr.: 〒305-8568 つくば市梅園1-1-1 産総研つくば中央第2
Phone: 029-861-5959
choreonoid-users-ja メーリングリストの案内