Boost logo

Boost Users :

Subject: Re: [Boost-users] [statechart] Substates in dll
From: Bill Clark (bill_at_[hidden])
Date: 2009-07-11 17:57:37


Hi Andreas,

I'm afraid I'm still not seeing a way to accomplish this (which could easily
mean that I'm missing something).

So taking the TuTest code as an starting point, here's what I would like to
be able to do:

- Put TuTest.cpp and TuTest.hpp in a dll, TuTest.dll, called by the main
program. Keep the initial transition in the cpp file, as in the test code.
- Make the Initial state react to EvX by transitioning to a new state, call
it MyState, defined in MyState.dll. MyState, in turn, would have its own
internal transitions and states, which it hides from clients by putting them
in its own cpp files.

In your reply you had said that the state dll, MyState.dll in this case,
won't have a link-time dependency on the state machine; it need only include
its header. This would be true if the state machine were implemented
entirely in the header. However, the header won't be enough if its initial
transition is hidden in a cpp file; the state would need to link with the
state machine. And similarly, in the state machine's cpp, it will be
necessary to link to MyState in order to transition to it. Again, we could
avoid this if MyState were implemented entirely in its header, but we want
to hide its details inside its cpp files.

As far as I've been able to tell, the same cyclic relationship would appear
no matter how we moved the functions around, e.g. by moving the react
function that takes us from Initial to MyState into MyState.dll. This would
also seem to cause error messages about inconsistent dll linkage, but
perhaps there are ways around that. I didn't think it was possible to split
the implementation of a class across multiple dlls. Even so, I don't see how
we could avoid dependencies in both directions.

>From what I can tell, the cyclic dependency is a consequence of the fact
that a state's type is parameterized on both its immediate outer state and
its initial inner state. It's possible to use forward references to make the
compiler happy with this, and if you're using static libraries there's no
problem. But if you try to split out parts of a state machine into
separately loadable components (dlls or shared objects), the linker will
necessarily be unable to resolve things in one direction or the other.

I hope the above is reasonably clear, and thanks for your assistance - I
really hope that there's something I've overlooked or misunderstood!

Bill

On Sat, Jul 11, 2009 at 2:18 AM, Andreas Huber <
ahd6974-spamboostorgtrap_at_[hidden]> wrote:

> Hi Bill
>
> Is there any way to partition a state machine using boost::statechart such
>> that the main state machine is in one dll, and its substates (and possibly
>> their substates) are in separate dll's?
>>
>
> Yes, that's possible, with one restriction: The inner initial state of each
> state must be in the same dll as the state itself, see below.
>
> It would seem that this would create a cyclic dependency.
>>
>
> The cyclic dependency only exists between the state and its inner initial
> state. The state does not need to have any knowledge of all its other inner
> states.
>
> Suppose you have
>> e.g. a simple statechart called MyStatechart containing an initial state
>> State1 which transitions to State2 in response to some event. Is it
>> possible
>> to implement MyStatechart and State1 in MyStatechart.dll, and State2 in
>> State2.dll?
>>
>
> It seems this should be possible. A prerequisite is that the transition
> from State1 to State2 must not be implemented with an ordinary
> sc::transition<> but with a sc::custom_reaction<>. By doing that, you are
> able to move the knowledge of the target state from the declaration (hpp
> file) to an ordinary function (which can reside in a cpp file), see
>
> <
> http://www.boost.org/doc/libs/1_39_0/libs/statechart/doc/tutorial.html#SpreadingAStateMachineOverMultipleTranslationUnits
> >
>
> for more information. Now, in order to really break the cycle, the
> *implementation* of State1::react should reside in State2.dll. Don't know
> whether that suits your needs, if not feel free to follow-up.
>
> Since the code for State1 will need to reference State2 (in order to
>> transition to it), MyStatechart.dll will have a dependency on State2.dll.
>> But since State2 is contained in MyStatechart, its type will have to look
>> something like
>>
>> struct State2: sc::state<State2, MyStatechart>
>> {
>> //...
>> };
>>
>> which means that State2.dll will have a dependency on MyStatechart.dll.
>>
>
> No, IIUC. It should be enough when MyStatechart.dll and State2.dll include
> the same header, e.g. MyStatechart.hpp. You might want to have a look at the
> TuTest*.* files in the test directory. These do not implement your use case,
> but at least illustrate how the importing/exporting required by some
> platforms can be done.
>
> HTH,
>
> --
> Andreas Huber
>
> When replying by private email, please remove the words spam and trap
> from the address shown in the header.
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net