1

I have a private static member variable of a class foo (std::vector<double> values). There is one object of foo capsulated in a dll (interface class and implementation class idiom). This is the header file 'foo.h':

class foo
{
public:
    foo();
    ~foo();

private:
    static std::vector<double> values;
};

And the definition file 'foo.cpp':

#include "foo.h"

std::vector<double> foo::values;

foo::foo()
{
    values.resize(10UL);
}

foo::~foo()
{
    for (auto& v :values)
    {
        v = 99.9;
    }
}

Foo is constructed inside the dll, where I have my interface class (file 'interface.h'):

class interface
{
public:
    interface();
    ~interface();

     foo myFoo;
};

extern "C" foo* getFooObject();

And a getter function in my 'interface.cpp' file:

#include "interface.h"

interface::interface(){}

interface::~interfacet(){}

interface myInterface;

extern "C"
{
      foo* getFooObject()
      {
            return &myInterface.myFoo;
      }
}

In my main programm I load the dll with ::LoadLibrary(libraryName) (Windows OS). When I perform ::FreeLibrary(libraryHandle) and set a breakpoint in the destructor ~foo() variables seems already destroyed. Can somebody help me with the lifetime of static member variables in dlls? How can I prevent that static member variables are already destroyed when the destructor is called?

Thank you in advance.

Probably a similar question:

c++ Static variables in dynamic DLL lifetime. or why they dead?

I use Visual Studio 2013 with the Intel Parallel Studio XE 2016.

Community
  • 1
  • 1
d.m.q.
  • 31
  • 4
  • 2
    Your question does not explain how is `foo` constructed. Is it constructed inside the dll and exposed via a factory function or a getter? Or maybe there is a single static instance of `foo` inside the dll that gets returned somehow? – Rudolfs Bundulis Mar 27 '17 at 13:55
  • You can't prevent, ~foo() must be called before FreeLibrary. – KonstantinL Mar 27 '17 at 14:11
  • @RudolfsBundulis : Thank you for your comment. I edited my question and added the Interface to show how foo is constructed and exposed. – d.m.q. Mar 28 '17 at 11:31
  • Your main question seems to be that your destructor is called more than once - which naturally should not be the case. You should verify that - just print out or log a counter each time it is called. And/or set a breakpoint in the destructor right after you call LoadLibrary(), and inspect the call stack to see what is calling the destructor more than once. Also verify that you are not copying your Foo object somewhere and are observing its destruction instead of the global object - your design is quite fragile unless you enforce Foo to be a singleton. – nos Mar 28 '17 at 11:35
  • @nos: Thanks for your advice. I inspected the desctructor right afte calling `::LoadLibrary()` and it is called only once, where `values` is already destroyed. – d.m.q. Mar 28 '17 at 12:20

1 Answers1

1

You are running into multiple issues here:

  1. Since you have split the code among multiple files, and both values and myInterface are defined as static variables you can't count on the destruction sequence (so actually, values could be destroyed before myInterface). If both were in the same compilation unit, you could count on that (see this).
  2. Even with a proper destruction order, the pointer obtained on the client side would be invalid after the call to FreeLibrary.

So the bottom line is that it is not unclear what you are trying to achieve (why do you want to use Run-Time Dynamic Linking instead of Load-Time Dynamic Linking?). Even if you are making a modular system that needs to load the stuff at runtime, design it properly so that the objects obtained from the dll do not exceed the life time of the library (e.g a manager class that properly destroys all objects create via factory functions by calling corresponding destructor functions before FreeLibrary is called).

Community
  • 1
  • 1
Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71