I am trying to a make plugin system which will have a header file for all plugins to include. In that header the version of the plugin system is defined in a #define like so:
PluginHeader.hpp:
#define PLUGIN_SYSTEM_VERSION "00.001"
class PluginSystem
{
public:
string GetSystemVersion(){return PLUGIN_SYSTEM_VERSION; }
void MyPluginDoStuff(){...}
}
I compile my plugin with this header in a dll and export it. Afterwards, i import it in the main application and i change the value of the #define in the calling application to be "00.002". If i call the method GetSystemVersion
in the dll, then i am getting the new value "00.002".
Is this the expected behavior? How can i make the dll keep its defined value?
It is neither expected nor unexpected behaviour. Your program has undefined behaviour, so any outcome (whether it seems "right" or not) is possible.
Your member function
PluginSystem::GetSystemVersion()
is defined (implemented) within its class definition, so is implicitly inline.The problem is, by having different definitions of the macro
PLUGIN_SYSTEM_VERSION
in different compilation units (e.g. in your DLL and in a separate source file that includes your header), you cause your program to have multiple definitions ofPluginSystem::GetSystemVersion()
(and, in fact, the whole classPluginSystem
) in your program. If those definitions aren't exactly the same, you're breaking the one-definition rule. Which for an inlined function (and for a class) means that all definitions seen by different source files must be identical.Breaking the one-definition rule means your program has undefined behaviour. Seeing different versions of an inline function being called in different compilation units (e.g. the DLL version called in some situations but not others) is one possible symptom of that.
If you want to have the function in the DLL, then
Although not technically necessary, I'd encourage you to avoid using macros (other than include guards) in the header (or, even, using a macro for it at all - there are alternatives). If you must have a macro
PLUGIN_SYSTEM_VERSION
, define it locally to the single source file that definesPluginSystem::GetSystemVersion()
. That avoids the possibility of confusing yourself (and increasing chances of getting unexpected behaviours) by having different incantations ofPLUGIN_SYSTEM_VERSION
(and code affected by it) in different parts of your program.