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@yahoo.com> 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 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@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users