|
@@ -18,7 +18,7 @@
|
|
|
|
|
|
|
|
/* Include this file in code that compiles with Panda to guarantee
|
|
/* Include this file in code that compiles with Panda to guarantee
|
|
|
that it is linking with the same version of the Panda DLL's that it
|
|
that it is linking with the same version of the Panda DLL's that it
|
|
|
- was compiled with. You should include it in one .cxx file only. */
|
|
|
|
|
|
|
+ was compiled with. */
|
|
|
|
|
|
|
|
/* We guarantee this by defining an external symbol which is based on
|
|
/* We guarantee this by defining an external symbol which is based on
|
|
|
the version number. If that symbol is defined, then our DLL's
|
|
the version number. If that symbol is defined, then our DLL's
|
|
@@ -26,14 +26,39 @@
|
|
|
DLL; but the system linker will prevent the DLL from loading with
|
|
DLL; but the system linker will prevent the DLL from loading with
|
|
|
an undefined symbol. */
|
|
an undefined symbol. */
|
|
|
|
|
|
|
|
|
|
+#ifndef CHECKPANDAVERSION_H
|
|
|
|
|
+#define CHECKPANDAVERSION_H
|
|
|
|
|
+
|
|
|
#include "dtoolbase.h"
|
|
#include "dtoolbase.h"
|
|
|
|
|
|
|
|
extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
|
|
extern EXPCL_DTOOL_DTOOLBASE int @PANDA_VERSION_SYMBOL@;
|
|
|
|
|
|
|
|
-#ifndef WIN32
|
|
|
|
|
-/* For Windows, exporting the symbol from the DLL is sufficient; the
|
|
|
|
|
- DLL will not load unless all expected public symbols are defined.
|
|
|
|
|
- Other systems may not mind if the symbol is absent unless we
|
|
|
|
|
- explictly write code that references it. */
|
|
|
|
|
-static int check_panda_version = @PANDA_VERSION_SYMBOL@;
|
|
|
|
|
|
|
+/* Just declaring the symbol isn't good enough. We need to force the
|
|
|
|
|
+ compiler and linker to preserve the external reference long enough
|
|
|
|
|
+ to end up in the output DLL. Therefore, we have to reference that
|
|
|
|
|
+ symbol somehow.
|
|
|
|
|
+
|
|
|
|
|
+ Forcing the compiler to include a reference in its output object
|
|
|
|
|
+ file is easy enough: just define a function that makes use of it
|
|
|
|
|
+ in some way. The problem is the linker, which will enforce the
|
|
|
|
|
+ C++ One-Definition Rule and get upset about said definition
|
|
|
|
|
+ appearing in multiple places in the program. We can appease the
|
|
|
|
|
+ linker by forcing the compiler to emit a weak symbol. Many
|
|
|
|
|
+ compilers have syntax to request this explicitly, but since it
|
|
|
|
|
+ varies from compiler to compiler, that wouldn't be very portable.
|
|
|
|
|
+
|
|
|
|
|
+ Fortunately, the C++ ODR itself has some exceptions, where a
|
|
|
|
|
+ definition can occur in multiple translation units *if and only if*
|
|
|
|
|
+ it's the same definition each time. In these cases, the compiler
|
|
|
|
|
+ must emit a weak symbol, because the ODR does not guarantee that
|
|
|
|
|
+ the same definition isn't repeated in any other translation units.
|
|
|
|
|
+ One such exception is template instantiation, which we use thus: */
|
|
|
|
|
+template<typename T>
|
|
|
|
|
+class CheckPandaVersion {
|
|
|
|
|
+public:
|
|
|
|
|
+ int check() { return @PANDA_VERSION_SYMBOL@; }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+template class CheckPandaVersion<void>;
|
|
|
|
|
+
|
|
|
#endif
|
|
#endif
|