|
From: Braden M. <br...@en...> - 2012-04-02 16:07:53
|
On Mon, 2012-04-02 at 10:51 -0400, Kevin Moule wrote:
> On Wed, Mar 28, 2012 at 1:57 PM, Braden McDaniel <br...@en...>wrote:
>
> > On Tue, 2012-03-20 at 16:17 -0400, Kevin Moule wrote:
> > > Hi,
> > >
> > > I've started using openvrml-0.18 from the SVN branch and have run into a
> > > bit of a problem. It seems that the following function
> > >
> > > openvrml::local::component_registry::component_registry()
> > > (component.cpp:343)
> > >
> > > will throw an exception if the env. variable OPENVRML_DATADIR is not
> > > defined and the registry key HKLM\SOFTWARE\OpenVRML\OpenVRML\DataDir is
> > not
> > > defined.
> > >
> > > This constructor gets call as part of the normal global variable
> > > initialization due to the follow:
> > >
> > > const openvrml::local::component_registry
> > > openvrml::local::component_registry_; (component.cpp:378)
> > >
> > > and if it throws it will lead to a low level application startup problem
> > > that can't be recovered from easily.
> > >
> > > I know the work around is to either define OPENVRML_DATADIR or create the
> > > registry key, but I don't like either of those solutions since they
> > require
> > > something outside of the application to function.
> >
> > Is that all that unusual on Windows? (Honest question.)
> >
> > The thinking here is that it's the job of an installer to set the
> > registry key appropriately.
> >
>
> I think it is the norm on Windows. However, I'm a fan of having an
> application
> be as independent as possible, and at the very least not relying on registry
> keys to be able to get an application started.
So the general problem is: how does one accomplish that goal when a DLL
(or program) depends (critically) on external resources?
> > > I'm wondering if this can be considered a bug and perhaps have the
> > > constructor changed to not throw an exception if the registry key is
> > > missing (and also any fallout from the boost::filesystem code).
> > >
> > > I've fixed this in my working copy by changing the throw declaration to
> > > only include std::bad_alloc and then wrapped the majority of the
> > > constructor in a try { ... } catch( const std::runtime_error &) {} to
> > > silently swallow the error. I've also attached a patch that might be
> > easier
> > > to read.
> >
> > Simply swallowing the error without doing anything about it isn't
> > appropriate. There needs to be a component specification store
> > somewhere; without it, you have no node implementations. How do you
> > propose to proceed without node implementations?
> >
>
> Throwing from a global constructor doesn't seem appropriate either, there
> is no way to recover from that.
The rationale behind this choice is that loading these things is
critical to the operation of the library; so if they don't get loaded,
loading can fail completely. The way to recover is to try loading the
DLL again (after fixing the problem).
Presumably this error *is* recoverable if you're loading the library at
run-time (via LoadLibrary or similar); but I haven't tried it. Of
course, the actual exception doesn't propagate in that instance; so a
nontrivial downside is that you don't have any idea why loading failed.
So, basically, you'd have to anticipate this situation; and if you're
doing that, you might as well check to make sure everything is properly
in place before loading the DLL in the first place.
The alternative to this setup is to have a library initialization
function that gets called explicitly. But then *everybody* has to call
it. It's not a very C++ way of doing things, IMO.
> I did run into the component store problem. Coming from an early version
> of 0.17 I didn't fully understand how component/node split worked. So, I
> will need to need to satisfy the component_registry's need for a store, I
> was
> just hoping to do that at runtime. I'm currently exploring ways to get an
> environment variable set prior to the DLL being loaded.
I don't see how depending on an environment variable being set
beforehand is any better than depending on a registry key being set
beforehand. Surely if you can set an environment variable, you can set a
registry key.
One possibility would be to have a default place to look when no
registry key is set--presumably somewhere relative to the location of
the DLL. But I still think it would be appropriate to throw if the
default location doesn't exist--so I think this doesn't actually solve
the problem you're trying to solve.
--
Braden McDaniel <br...@en...>
|