Am 20.10.2015 um 17:28 schröbte Viacheslav Usov:
> When embedding Lua into an application written in C++, it is pretty much a
> requirement to compile the Lua library in the C++ mode, to ensure that
> Lua's error mechanism interoperates properly with C++'s destructors.
I think another safe way is to not use objects with non-trivial
destructors in your binding functions (i.e. wherever `lua_error()` might
be called), and transform all exceptions thrown by your application code
into Lua errors.
> Lua supports being compiled as C++, and once the compiler is
> instructed to compile the code as C++, it will automatically use
> throw/try/catch.
>
> This, however, has a side effect: all of Lua's functions are then defined,
> in C++ terms, as extern "C++". Which is, unfortunately, a problem when Lua
> is linked statically [1] and then another C-language library using Lua
> needs to be linked statically with the same application. Linking such a
> library (let's call it X) with the rest of the application (containing Lua
> compiled in the C++ mode) will fail, because the Lua API functions will be
> decorated according to extern "C++", while X expects extern "C". It may be
> argued that X could be recompiled as C++, but C and C++ are not fully
> compatible, sometimes with run-time differences only [2], so this is
> generally not advisable.
>
> In a project where I had this problem, I resolved it by altering the
> following definition in luaconf.h:
>
> original:
>
> #define LUA_API extern
>
> modified:
>
> #ifdef __cplusplus
> #define LUA_API extern "C"
> #else
> #define LUA_API extern
> #endif
>
> As far as I can tell, nothing else is needed to resolve the issue. I
> suggest that this be incorporated into Lua's official source.
You shouldn't throw exceptions from `extern "C"` functions, especially
if real C code is involved. So the whole point of compiling Lua as C++
becomes moot. Also `extern "C" int (*)( lua_State* )` and `extern "C++"
int (*)( lua_State* )` are distinct types not convertible to each other,
and currently you can only pass one *or* the other to the Lua API
functions, depending on how the Lua library was compiled. So if you have
C code *and* C++ code, and both use `lua_CFunction`s, your only
standards compliant option is to compile Lua as C and use `extern "C"`
in your C++ code for your binding functions.
>
> I have thought about another way of fixing this, but I am unsure about its
> true merit. The try/catch/throw keywords, when compiled in the C++ mode,
> are only used once each, and in a very simple way, without much dependency
> on the rest of the library. Therefore, this C++ code can be extracted and
> placed in a separate file, one with a C++ extension, and only be compiled
> when the C++ error behaviour is needed. I do not think Lua needs to be
> compiled as C++ for any other reason. Then the rest of library need only
> support being compiled strictly as C, which may require less of an effort
> to ensure C/C++ standard conformance. As stated above, I am not really sure
> whether the benefit is real.
Real C code is incompatible with exceptions, so most Lua API functions
will need to be `extern "C++"` anyway just because they could be on the
call stack when an error/exception is thrown.
>
> Cheers,
> V.
>
Philipp