5

I have static library with static member. This library statically linked to main application and to one of its plugins. Looks like static variable initializing both in main (application) and in dll (plugin).

Question: How to avoid static variable reinitialization when dynamic library loading. Or may be I missing something simple?

More information:

This is simple static library, that contains static member and it's getter and setter:

orbhelper.h

class ORBHelper {
    static std::string sss_;
public:
    static std::string getStr();
    static void setSTR(std::string str);
};

orbhelper.cpp

std::string ORBHelper::sss_ = "init";

static std::string ORBHelper::getStr()
{
    std::cerr << "get " << sss_.c_str() << std::endl;
    return sss_;
}
static void ORBHelper::setSTR(std::string str)
{
    sss_ = str;
    std::cerr << "set " << sss_.c_str() << std::endl;
}

This library used in main.cpp and also in another dynamic library, that is loaded in main. In main.cpp I set the static string and in one of dynamic library function I want to get it.

Setting static variable in main:

main.cpp

...
ORBHelper::setStr("main");
std::cerr << ORBHelper::getStr().c_str() << std::endl; //prints 'main'
//then loading library
...

Then getting variable value in dll:

hwplugin.cpp

...
std::cerr << ORBHelper::getStr().c_str() << std::endl; //prints 'init' instead of 'main'
...

Looks like static variable has been initialized twice. First – before main.cpp, second – when dynamic library loaded. Static lib with static class linked both to main app and to dynamic lib.

P.S. too many words 'static' in my question, I know =)

uni
  • 539
  • 1
  • 9
  • 21
  • If you link statically, you probably get *two* instances of the variable, one in the exe and one in the DLL. – Bo Persson May 12 '12 at 07:27
  • I checked the address of a variable (printf("%p",&sss);) and found that it is the same variable. – uni May 12 '12 at 07:32
  • 2
    I have recently had the same problem (http://stackoverflow.com/q/10520587/509868); got two usable solutions (1: turn the static lib into a (second) DLL; or 2: add a function to your existing DLL that initializes the problematic stuff in the static lib) – anatolyg May 12 '12 at 07:39
  • 1
    If you have run-time loading, it might be preferable to build some global context object in your main application, and then pass a reference or pointer to that to your dynamic library initialization. The context object could easily contain enough state information so that each loaded library can figure out whether or not it needs to do more work. – Kerrek SB May 12 '12 at 11:32

1 Answers1

0

Yes, you have two instances of the helper class.

The DLL should be linked against the executable that links the static class in and use that to resolve the helper class. Do not link the DLL with the static library, but link it against the executable itself.

Antti Huima
  • 25,136
  • 3
  • 52
  • 71
  • You cannot do this, you'll get linker errors when building the dll. – Matteo Italia May 12 '12 at 07:40
  • I added printf("%p",&sss_); in every function of helper and every time it prints the same address. Doesn't that mean that there is only one instance of helper? – uni May 12 '12 at 07:40
  • Hmm... possibly, but then it is the static initializer that is still run twice even if the symbols are mapped to the same memory address. – Antti Huima May 12 '12 at 08:07