special case luabridge for windows/MSVC
luabridge uses static fn addresses to identify classes. Windows uses different addresses for *identical* static functions in libardour.dll and ardour.exe This solves the issue by moving the all functions from a header-only implementation into libardour.
This commit is contained in:
parent
4eba3869fe
commit
8002b2d26e
|
@ -38,6 +38,7 @@
|
|||
#include "ardour/interthread_info.h"
|
||||
#include "ardour/lua_api.h"
|
||||
#include "ardour/luabindings.h"
|
||||
#include "ardour/luaproc.h"
|
||||
#include "ardour/meter.h"
|
||||
#include "ardour/midi_track.h"
|
||||
#include "ardour/midi_port.h"
|
||||
|
@ -55,6 +56,96 @@
|
|||
|
||||
#include "LuaBridge/LuaBridge.h"
|
||||
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
/* luabridge uses addresses of static functions/variables to identify classes.
|
||||
*
|
||||
* Static symbols on windows (even identical symbols) are not
|
||||
* mapped to the same address when mixing .dll + .exe.
|
||||
* So we need a single point to define those static functions.
|
||||
* (normally they're header-only in libs/lua/LuaBridge/detail/ClassInfo.h)
|
||||
*
|
||||
* Really!! A static function with a static variable in a library header
|
||||
* should never ever be replicated, even if it is a template.
|
||||
* But then again this is windows... what else can go wrong.
|
||||
*/
|
||||
|
||||
template <class T>
|
||||
void const*
|
||||
luabridge::ClassInfo<T>::getStaticKey ()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void const*
|
||||
luabridge::ClassInfo<T>::getClassKey ()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void const*
|
||||
luabridge::ClassInfo<T>::getConstKey ()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
void*
|
||||
luabridge::getIdentityKey ()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
|
||||
/* ...and this is the ugly part of it.
|
||||
*
|
||||
* We need to foward declare classes from gtk2_ardour.
|
||||
* This is needed because some of the classes use objects from libardour
|
||||
* as function parameters and the .exe would re-create symbols for libardour
|
||||
* objects.
|
||||
*
|
||||
* Classes which don't use libardour symbols could be moved to
|
||||
* gtk2_ardour/luainstance.cc, but keeping this here reduces code
|
||||
* duplication and does not give the compiler a chance to even think
|
||||
* about replicating the symbols.
|
||||
*/
|
||||
|
||||
#define CLASSKEYS(CLS) \
|
||||
template void const* luabridge::ClassInfo< CLS >::getStaticKey(); \
|
||||
template void const* luabridge::ClassInfo< CLS >::getClassKey(); \
|
||||
template void const* luabridge::ClassInfo< CLS >::getConstKey();
|
||||
|
||||
#define CLASSINFO(CLS) \
|
||||
class CLS; \
|
||||
template void const* luabridge::ClassInfo< CLS >::getStaticKey(); \
|
||||
template void const* luabridge::ClassInfo< CLS >::getClassKey(); \
|
||||
template void const* luabridge::ClassInfo< CLS >::getConstKey();
|
||||
|
||||
CLASSINFO(MarkerSelection);
|
||||
CLASSINFO(TrackSelection);
|
||||
CLASSINFO(TrackViewList);
|
||||
CLASSINFO(TimeSelection);
|
||||
CLASSINFO(RegionSelection);
|
||||
CLASSINFO(PublicEditor);
|
||||
CLASSINFO(Selection);
|
||||
CLASSINFO(ArdourMarker);
|
||||
|
||||
namespace Cairo {
|
||||
class Context;
|
||||
}
|
||||
CLASSKEYS(Cairo::Context);
|
||||
CLASSKEYS(std::vector<double>);
|
||||
CLASSKEYS(std::list<ArdourMarker*>);
|
||||
CLASSKEYS(std::bitset<47ul>); // LuaSignal::LAST_SIGNAL
|
||||
CLASSKEYS(ArdourMarker*);
|
||||
CLASSKEYS(ARDOUR::RouteGroup);
|
||||
CLASSKEYS(ARDOUR::LuaProc);
|
||||
|
||||
#endif // end windows special case
|
||||
|
||||
/* Some notes on Lua bindings for libardour and friends
|
||||
*
|
||||
* - Prefer factory methods over Contructors whenever possible.
|
||||
|
@ -582,7 +673,6 @@ LuaBindings::common (lua_State* L)
|
|||
.addFunction ("output_map", (ARDOUR::ChanMapping (PluginInsert::*)(uint32_t) const)&PluginInsert::output_map)
|
||||
.addFunction ("set_input_map", &PluginInsert::set_input_map)
|
||||
.addFunction ("set_output_map", &PluginInsert::set_output_map)
|
||||
|
||||
.endClass ()
|
||||
|
||||
.deriveWSPtrClass <AutomationControl, PBD::Controllable> ("AutomationControl")
|
||||
|
|
|
@ -36,6 +36,15 @@ template <class T>
|
|||
class ClassInfo
|
||||
{
|
||||
public:
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
/* static symbols on windows (even identical symbols) are not
|
||||
* mapped to the same address when mixing .dll + .exe.
|
||||
* the implementation is moved to libardour/gtk2_ardour.
|
||||
*/
|
||||
static void const* getStaticKey ();
|
||||
static void const* getClassKey ();
|
||||
static void const* getConstKey ();
|
||||
#else
|
||||
/** Get the key for the static table.
|
||||
|
||||
The static table holds the static data members, static properties, and
|
||||
|
@ -69,5 +78,6 @@ public:
|
|||
static char value;
|
||||
return &value;
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -51,11 +51,15 @@
|
|||
6. Our metatables have "__metatable" set to a boolean = false.
|
||||
7. Our lightuserdata is unique.
|
||||
*/
|
||||
#ifdef PLATFORM_WINDOWS
|
||||
extern void* getIdentityKey ();
|
||||
#else
|
||||
inline void* getIdentityKey ()
|
||||
{
|
||||
static char value;
|
||||
return &value;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
Interface to a class pointer retrievable from a userdata.
|
||||
|
|
|
@ -33,13 +33,14 @@ def build(bld):
|
|||
if bld.is_defined('WINDOWS_VST_SUPPORT') and bld.env['build_target'] != 'mingw':
|
||||
return
|
||||
|
||||
if bld.env['build_target'] != 'mingw':
|
||||
# TEST/DEVEL TOOL #######################
|
||||
obj = bld (features = 'cxx c cxxprogram')
|
||||
obj.source = 'devel.cc'
|
||||
obj.target = 'devel'
|
||||
obj.uselib = ['SIGCPP', 'READLINE']
|
||||
obj.use = ['liblua']
|
||||
obj.install_path = None
|
||||
obj = bld (features = 'cxx c cxxprogram')
|
||||
obj.source = 'devel.cc'
|
||||
obj.target = 'devel'
|
||||
obj.uselib = ['SIGCPP', 'READLINE']
|
||||
obj.use = ['liblua']
|
||||
obj.install_path = None
|
||||
#########################################
|
||||
|
||||
# commandline luasession wrapper
|
||||
|
|
Loading…
Reference in New Issue
Block a user