Skip to content

Commit

Permalink
A sad workaround for a sad misery with Python bindings on Windows.
Browse files Browse the repository at this point in the history
  • Loading branch information
mosra committed Oct 23, 2019
1 parent de95edd commit 909887a
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 7 deletions.
4 changes: 3 additions & 1 deletion doc/changelog.dox
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ See also:
@ref Corrade::Containers::Array instead of being deleted
- Global state used by @ref GL::Context and @ref Audio::Context is no longer
duplicated when Magnum is built statically and linked to more than one
dynamic library or executable.
dynamic library or executable. This works on all platforms except for
Python bindings on Windows at the moment, where the workaround is to build
both Corrade and Magnum dynamically.
- The [base-qt](https://github.com/mosra/magnum-bootstrap/tree/base-qt)
bootstrap project is fixed to use OpenGL 4.1 on macOS instead of being
stuck on 2.1 (see [mosra/magnum-bootstrap#22](https://github.com/mosra/magnum-bootstrap/issues/22))
Expand Down
2 changes: 1 addition & 1 deletion src/Magnum/Audio/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ namespace {
Context*& windowsCurrentContext() {
/* A function-local static to ensure it's only initialized once without any
race conditions among threads */
static Context** const uniqueGlobals = reinterpret_cast<Context**>(Magnum::Implementation::windowsWeakSymbol("magnumAudioUniqueCurrentContext"));
static Context** const uniqueGlobals = reinterpret_cast<Context**>(Magnum::Implementation::windowsWeakSymbol("magnumAudioUniqueCurrentContext", &magnumAudioUniqueCurrentContext));
return *uniqueGlobals;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Magnum/GL/Context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,7 +522,7 @@ namespace {
Context*& windowsCurrentContext() {
/* A function-local static to ensure it's only initialized once without any
race conditions among threads */
static Context*&(*const uniqueGlobals)() = reinterpret_cast<Context*&(*)()>(Magnum::Implementation::windowsWeakSymbol("magnumGLUniqueCurrentContext"));
static Context*&(*const uniqueGlobals)() = reinterpret_cast<Context*&(*)()>(Magnum::Implementation::windowsWeakSymbol("magnumGLUniqueCurrentContext", reinterpret_cast<void*>(magnumGLUniqueCurrentContext)));
return uniqueGlobals();
}

Expand Down
11 changes: 8 additions & 3 deletions src/Magnum/Implementation/WindowsWeakSymbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,23 @@

#include "WindowsWeakSymbol.h"

#include <Corrade/Utility/Assert.h>
#include <cstdio>

#define WIN32_LEAN_AND_MEAN 1
#define VC_EXTRALEAN
#include <windows.h>

namespace Magnum { namespace Implementation {

void* windowsWeakSymbol(const char* name) {
void* windowsWeakSymbol(const char* name, void* backup) {
/* FARPROC?! I want either a function pointer or a variable pointer */
void* address = reinterpret_cast<void*>(GetProcAddress(GetModuleHandleA(nullptr), name));
CORRADE_INTERNAL_ASSERT(address);
/* This shouldn't fail, except in Python, where it's a sad, sad misery. */
if(!address) {
std::fprintf(stderr, "Cannot query global symbol %s and make it unique\n"
"across DLLs. App may misbehave, sorry. Build Magnum as dynamic as a workaround.\n", name);
address = backup;
}
return address;
}

Expand Down
2 changes: 1 addition & 1 deletion src/Magnum/Implementation/WindowsWeakSymbol.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

namespace Magnum { namespace Implementation {

void* windowsWeakSymbol(const char* name);
void* windowsWeakSymbol(const char* name, void* backup);

}}

Expand Down

0 comments on commit 909887a

Please sign in to comment.