Jump to content
  • Advertisement
Sign in to follow this  
Mortilles

Static class members in dll

This topic is 3854 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. I have problem with initialization of static class members in dll. I'm developing interface exporting framework to facilitate work with dll files. During my work i've spotted that something is not ok. Let suppose that we have file test.cpp like this: /**********test.cpp*************/ unsigned int registerNewImpl(const char* p_impl_name); class TestImpl : public ITestInterface { public: virtual unsigned int getImplId() { return m_impl_id; } private: static unsigned int m_impl_id; }; unsigned int TestImpl::m_impl_id = registerNewImpl("TestImpl"); /*******************************/ Now I have a question. When TestImpl::m_impl_id will be initialized? During dll load time or when first used?

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Mortilles
Now I have a question. When TestImpl::m_impl_id will be initialized?
During dll load time or when first used?
Compile it and see? My guess (And it's just a guess) is that it'll be the same as EXEs, and initialised at load time.

Share this post


Link to post
Share on other sites
I've compiled it. The problem is that TestImpl::m_impl_id is initialized but registerNewImpl() function was not called.... I have no idea what is wrong.

Share this post


Link to post
Share on other sites
hi,

nothing is wrong. a static member variable is created on the heap, meaning that the object doesn't need to be created.

you should be very careful using static variables with dll's.. if you exe (main application that loads the dll) includes the header then you will get two instances of the static variable.

a dll has it's own heap and so doesn your exe, so be warned.

hope this helps,
Peter Wraae Marino

Share this post


Link to post
Share on other sites
I belive you meant stack. Dll when loaded share the same addressing space with exe that loaded them. That way it is possible to access data by the same pointer by exe and dll. Back to main subject...
I want to do something like this:

/**file interface.h**/
/**Just a header**/

class IBase
{
public:
virtual void incRef() = 0;
virtual void decRef() = 0;
};

typedef IBase* (*factoryFunc)();

class IRegistry
{
public:
virtual void registerFactory(factoryFunc p_f);
};

class IFactRegistry
{
public:
static unsigned int registerFactory(factoryFunc p_f);
static unsigned int getFactCount();
static factoryFunc getFact(unsigned int p_i);
};

class ITest : public IBase
{
public:
virtual void someFunc() = 0;
};

/**file impl.cpp**/
/**This file will be dll**/

class Test : public ITest
{
public:
ITest()
: m_ref_count(0)
{ }
virtual void incRef()
{ ++m_ref_count; }
virtual void decRef()
{
--m_ref_count;
if (m_ref_count == 0)
delete this;
}
virtual void someFunc()
{ }
private:
unsigned int m_ref_count;
};

class TestFactory
{
public:
static IBase* createInst()
{ return new Test; }
private:
static unsigned int s_fact_id;
};

unsigned int TestFactory::s_fact_id =
IFactRegistry::registerFactory(createInst);

extern "C" __attribute__((dllexport)) DllEntyPoint(IRegistry* p_reg)
{
for (int i = 0; i < IFactRegistry::getFactCount(); ++i)
p_reg->registerFactory(IFactRegistry::getFact(i));
};

End...

That is little messy and I will leave IRegistry and IFactRegistry implementation because they are all good.
The problem is that I don't know is that good thinking to register factories that way. Any ideas???

Share this post


Link to post
Share on other sites
No, they are definitely made on the heap. The stack is reserved only for locals, parameters, etc. DLLs are loaded into the same address space as the host EXE, but that does not mean that they share resource pools necessarily.

My gut agrees with Evil Steve that it should be initialized at load-time, but whenever you're dealing with cross-DLL or even across compilation units (see the dreaded static initialization order problem) you get into rather unintuitive behavior. I'd read up on DLLs in your OS/API docs.

Share this post


Link to post
Share on other sites
When you initalize a global or static member value outside of a function in your main.cpp, that code gets run by the CRT at some point after the real program entry point and before main or WinMain is called. The CRT will call registerNewImpl and assign the value for you. Now I'm not a DLL expert, but I'm reasonably sure that when you load a DLL all the work is done by Windows without any intervention from the CRT. This would certainly explain why your line of code for initialization fails to run. I'm pretty sure that if you want any initialization like that done, you have to do it yourself in DllMain. But again I'm not an expert on this, so I could be wrong.

Share this post


Link to post
Share on other sites
Quote:
Original post by Crisium

a dll has it's own heap and so doesn your exe, so be warned.



That's not always true. If they're both using the same CRT (by loading the same version of the CRT from a DLL), they'll both have the same heap. Also Win32 memory allocation functions must be capable of working across the DLL boundary, considering there are Win32 functions that will return allocated strings that the app is responsible for deallocating.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!