Function definitions in headers of a DLL
Hi,
first excuse my poor english.
I have a problem with a project, that worked fine under Windows (using
VC7) and Linux (using gcc) until a part of it was put into a DLL.
Since then, the Windows version doesn't work anymore. I've found the
problem, but can't solve it.The context of the problem in the project
is quite complex, hence I isolated it:
There is a DLL which contains a baseclass A, which has a static method
generate_id(). For every call, this method returns a unique id, by
incrementing a static variable. Every subclass of A has a static
method static_id(), which uses generate_id() to get a unique id at its
first call and simply returning this id in every following. The
problem is, that the implementation of static_id() must be in the
class definition in the header file, because the subclasses are
defined by macros.
Under linux this works perfect, even now with a DLL, but under Windows
a subclass has another static_id in the DLL as outside of it (in the
DLL client).
The following code illustrates the problem:
TestDll.h
#define EXPORT __declspec(dllexport)
class A
{
public:
EXPORT static int generate_id();
};
class B : public A
{
public:
EXPORT static int static_id()
{
static int id = 0;
if( !id )
id = A::generate_id();
return id;
};
};
class Container {
public:
EXPORT Container();
A* a;
};
TestDll.cpp
int A::generate_id()
{
static int id_counter = 0;
return ++id_counter;
}
Container::Container()
{
a = new B();
cout << ( (B*)a )->static_id();
}
The problem can be seen in the following behaviour of a DLL client:
Container* t = new Container();
returns 1, while the following call of
cout << B::static_id();
returns 2.
I think the reason for that is, that client and DLL are, caused by
inline expansion, using different "instances" of the method
static_id() (if I put the definition of static_id() in the cpp file
everything works fine, but due to the use of macros, I can't do that
in my project, as I said).
But even by using the compiler switch /Ob0 or a #pragma
auto_inline( off ) the microsoft compiler can not be prevented from
that inline expansion. Until today I thought that only to do an inline
expansion is an advice, not that the compiler is forced to do inlining
even if I say not to.
Any suggestions?
Grateful for every help
Marcel