Patrick's suggestion to return a LibraryHandle reminds me that I was originally a bit confused that there was no object representing a library.<div><br></div><div>Say you want to unload a plugin library from your running system.  You think your code has called unloadLibraryForClass() enough times for the right classes, but for some reason it is not unloading.  Without changing pluginlib, there is no way to ask pluginlib  why it is not unloading it (or if it is trying and failing).</div>
<div><br></div><div>If there were a pluginlib::Library class, it could hand you the list of instantiated classes with ref counts.  This is just for debugging purposes, but then our customers are programmers.</div><div><br>
</div><div>Dave</div><div><br><div class="gmail_quote">On Thu, Feb 9, 2012 at 5:06 PM, Patrick Mihelich <span dir="ltr"><<a href="mailto:mihelich@willowgarage.com">mihelich@willowgarage.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On Thu, Feb 9, 2012 at 12:55 PM, Dirk Thomas <span dir="ltr"><<a href="mailto:dthomas@willowgarage.com" target="_blank">dthomas@willowgarage.com</a>></span> wrote:<br></div><div class="gmail_quote"><div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">


<div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
While I like boost::shared_ptr, it is not always possible to use it nicely.<br>
<br>
In rviz I have plugin classes which are subclasses of QWidget (from Qt GUI library).  These objects are automatically deleted by Qt when their parent widgets are deleted.  I can be notified of their<br>
deletion by Qt, and call an "unload" or "decrement-reference-count" function, but it is not easy to use these QWidget pointers inside boost::shared_ptr without getting double-deletion crashes.<br>
</blockquote>
<br></div>
That sounds like a very reasonable use case.<br>
Automatically deleting and unloading is a nice feature but might not always be desired.<br>
Having the option to get a raw pointer (as before) and take care of garbaging stuff manually would be great.</blockquote></div><div><br>I don't like this, but don't see a clearly better solution.<br><br>So we have the problem that the shared_ptr is actually managing two resources - the lifetime of the object, and the lifetime of the loaded library (which must outlive all objects using it). The question is can we decouple those in a sane way. If we give up knowledge of the object lifetime, we also give up the ability to automatically manage the library lifetime.<br>


<br>One slightly different approach:<br><br><span style="font-family:courier new,monospace">T* getInstance(const std::string& lookup_name, LibraryHandle& handle);</span><br><br>Where the additional output LibraryHandle (could just be a shared_ptr typedef) represents the library lifetime, and decrements the lib ref count when it's destroyed. The user is responsible for making sure handle outlives the returned object. The advantages are that we don't have to expose [un]loadLibraryForClass() functions forever, and we make responsibility for the library lifetime explicit.<br>

<br></div><blockquote class="gmail_quote" style="margin:0pt 0pt 0pt 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div class="im"><div>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
pluginlib::ClassLoader could have two interfaces, one which gives a shared_ptr and manages the reference count for the library itself, and another which gives a raw pointer and increments the ref<br>
count and also has a decrement-ref-count function.<br>
</blockquote>
<br></div></div><div class="im">

I propose the following names to make clear what the difference is (of course with a more detailed doc-string):<br>
<br>
  boost::shared_ptr<T> getManagedInstance(const std::string& lookup_name)<br>
<br>
  T* getInstance(const std::string& lookup_name)<br></div></blockquote><div><br>In any case I'd reverse the naming convention - have getInstance() return a shared_ptr and, say, getUnmanagedInstance() return T*. We should make the encouraged usage easier, and discourage the advanced/unsafe usage with a longer name.<br>


<br>Cheers,<br>Patrick<br>
</div></div>
<br>_______________________________________________<br>
ros-users mailing list<br>
<a href="mailto:ros-users@code.ros.org">ros-users@code.ros.org</a><br>
<a href="https://code.ros.org/mailman/listinfo/ros-users" target="_blank">https://code.ros.org/mailman/listinfo/ros-users</a><br>
<br></blockquote></div><br></div>