class Foo
{
public:
/// m_iterator = m_myList.begin().
void reset_first();
/// check the end and set v = *m_iterator++
bool get_next(int& v);
private:
typedef std::list<int> IntList;
IntList m_myList;
IntList::iterator m_iterator;
};
Foo foo;
foo.reset_first();
int value;
while(foo.get_next(value))
{
// ...
}
But I met a question when I actually use this kind of interface, it only suit for the single pass traversal. But it can not deal with two or more pass traversal, like this:
It is because I keep only one iterator inside my class. Is there any good way to resolve this, or some way and deal with STL container directly and saftity.
For some of the STL implement like microsoft visual studio, they use static variable in the template. So there will two copy of the static variable in different DLL, and their value can not sync.
The MS said it should export the STL template instance, but I am not sure whether this problem will occur on other compiler or platform. And I see many expert always warning me not to pass a STL container cross DLL.
Even pointer of reference is not safe.
It because dll is always need link, and the code will generate twice in two different dll.
The first thing is hard to make sure the two copy of code is all the same, for there have different macro and code generate options in two dll.
Even all the macros and compile options is the same, there still have the problem about static variable. If the template use a static variable, this variable will copy twice in two dll. Althrouth I get a pointer of a STL object, but the code to run it is inside this DLL.
For example if a template class has a static variable a for counting the instance number of the class. If cross the dll, the counter will have two copy, and the counting value is not accurate.
I am not sure whether I am understand this problem well, or is there have any way to resolve this?
Thank you.
If you take the view that C++ DLLs implement libraries with classes/functions as the only interface (not exported data), you'll never have a problem and using a WIN32 DLL will be as safe and equivalent to using a POSIX shared library.
In fact what I want to ask is whether the custom dll can keep the iterator of a STL container in the producer dll, it a normal way to deal with multi-pass traversal.
I am afraid of the static variable because it hide behind the interfaces and I can not make sure the operation will not use the static variable, for there have kinds of implement of STL.
And kbw, I am not sure about the mean of "only interface", is there any example or something? Thank you.
Is the container static? If so, why doesn't it have a context?
By interface, I mean means of using the DLL.
I'm really trying to find out what's in your DLL and how are you accessing it. I'm trying to understand if you have a static container and want to expose an interator on that.
In my view, a reasonably thought out interface doesn't have such constructs. You'd expect to see classes and possbly creator functions, but certainly no direct access to data.
What I mean is not a static STL container. Think a simple template class like this:
template<typename T>
class Test
{
public:
Test()
{
++ms_instanceCounter;
}
In the A.dll, I use it like this:
Test<int>* get_test()
{
return new Test<int>;
}
And I export the function get_test, in B.dll I use it:
Test<int>* t = get_test();
assert(Test<int>::get_instance_count() == 1);
The assert may not pass because the static ms_instanceCounter will have two copy in both dll. And I call the function get_test, the ms_instanceCounter in A.dll increase, but the ms_instanceCounter in B.dll is still 0.
I can not make sure the STL implement do not fall into this way, but I know at least MS STL has this problem.
I wonder the static variable problem when using the template will not happend under linux when using the shared object?
Or the STL implement in gcc compiler is not using any static variable.
I managed to reproduce this multiple static instance thing.
1. Create DLL A with a static variable.
2. Create a function AF in DLL A that returns the address of the static.
3. Create DLL B that uses DLL A.
4. Create a function BF in DLL B that returns the address of the static by calling AF.
5. In your program, dynamically load DLL A/AF and DLL B/BF and call them. The addresses returned are different.
The program must have no link time knowledge of DLL A or DLL B.
I have to say, I have never knowingly had a problem with this.
I would think that libstdc++ would provide single instantiations all of the statics if there are any. I'm not aware
of any, nor am I aware of any such problems with gcc, and I use both the STL and shared objects quite
extensively (passing containers back and forth).
And the most terrible thing is the microsoft said this:
Also note that some STL containers (map, set, queue, list, deque) cannot be exported. Please refer to the More Information section to follow for a detailed explanation.
So only vector can export, I think I am more and more hate MS.
I think you've conflated two distinct issues. You have to solve them seperately.
1. How to deal with exporting STL containers.
2. How to deal with globals/statics in DLL instances.
Well, At first I know that STL containers can not cross DLLs, and I want to find out a method to deal with multi-pass traversal a container with an interface encapsulated.
It seems most of the time I was explaining why the STL containers can not cross DLL.
Let's back to the major subject, is there any suggestion to encapsulate a STL container and provide the ability of multi-pass traversal.