I have a multithreaded application. I declare a class with a static member in a shared library.
Printing the address of the member from different threads from different libraries shows different results.
//declaration
template <class OBJECT>
struct Container
{
static int m_member;
};
template <class OBJECT>
int Container<OBJECT>::m_member;
// printing
cout << (void*) &Container<int>::m_member << endl;
How could that be?
If you have different libraries, (I'm guessing different dynamic libraries), then you may have some duplication of both code and static variables.
The exact details will depend on the particular dynamic library technology you are using. I'd say that, for example, in Windows DLLs you will have duplicated code and variables, but in Linux SOs you will not.
Anyway, you should give more details on the Operating System and the layout of your project.
UPDATE: Ahh, but your class is a template! Template instantiations in a shared library are a strange beast! To make sure that only one copy of your class is used across all the process you have to explicitly instantiate the template and make sure that this instantiation is exported in the SO, and that it is used from the client code. The details vary with the compiler, but you can check how the std::string
is done, for example:
In the header file:
namespace std
{
extern template class basic_string<wchar_t>;
}
In the source of the library:
namespace std
{
template class basic_string<wchar_t>;
}
Naturally you need to know in advance which instantiations will be needed of your template. Obviously, the SO cannot export an instantiation that uses a type it knows nothing about.
UPDATE: Ahh, but you have two different libraries instantating the template... then if both libraries define the explicit instantiation as extern
the shared ELF magic should merge both instantiations into one.
YET ANOTHER UPDATE: After playing with templates and shared objects, it usually just works. My guess now is that you are compiling the libraries with -fvisibility=hidden
or similar. If that is the case, it would be enough just to write:
template <class OBJECT>
struct __attribute__((visibility("default"))) Container
{
static int m_member;
};
To make the specializations of the template to enter the dynamic symbol table, and thus avoid the duplication.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With