-
-
Notifications
You must be signed in to change notification settings - Fork 537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incompatibility of pointers to base and derived classes in Lua function calls #1532
Comments
So, I've created a test case that Short test case description:
Code: #include <iostream>
#include <sol/sol.hpp>
//#define VERBOSE
#ifdef VERBOSE
#define LOG_V(...) printf(__VA_ARGS__)
#else
#define LOG_V(...)
#endif
// base class
class Foo {
public:
Foo() {
LOG_V("ctor\n");
}
~Foo() {
LOG_V("dtor\n");
}
};
// derived class
class Bar: public Foo {};
template<typename T> static void registerType(sol::table &table);
template<> void registerType<Foo>(sol::table &table) {
if (table["Foo"].valid())
return;
auto foo = table.new_usertype<Foo>("Foo");
LOG_V("Foo registered\n");
}
template<> void registerType<Bar>(sol::table &table) {
if (table["Bar"].valid())
return;
auto bar = table.new_usertype<Bar>("Bar", sol::base_classes, sol::bases<Foo>());
LOG_V("Bar registered\n");
}
static bool testEnvCount(int envCount) {
sol::state state;
std::vector<sol::environment> envs(envCount);
// create environments
for (auto &env : envs)
env = sol::environment(state, sol::create, state.globals());
auto cfgEnv = [&state](sol::environment &env) {
registerType<Bar>(env);
registerType<Foo>(env);
state.script("function func(foo) doSomethingWithFoo(foo) end", env);
env["doSomethingWithFoo"] = [](Foo *foo) {
LOG_V("[doSomethingWithFoo] Foo: %ti\n", (ptrdiff_t) foo);
};
};
// configure environments
for (auto &env : envs)
cfgEnv(env);
Bar bar;
auto callFunc = [bar_ptr = &bar](sol::environment &env) {
auto result = env["func"].get<sol::function>()(bar_ptr);
if (!result.valid()) {
sol::error error = result;
LOG_V("%s\n", error.what());
}
return result.valid();
};
// call Lua function "func"
for (auto &env : envs) {
if (!callFunc(env)) {
return false;
}
}
return true;
}
int main() {
constexpr int testFrom = 1;
constexpr int testTo = 30;
for (int i = testFrom; i <= testTo; ++i) {
if (testEnvCount(i)) {
std::cout << "OK for envCount = " << i << "\n";
} else {
std::cout << "Failed for envCount = " << i << "\n";
}
}
return 0;
} Output: 1st run
2nd run
Sol error message:
In the example above, switching to v3.2.3 helps, as it described in #1523. However, unfortunately, in my project it didn't help. The only available "workaround" is the one described at the end of the first comment. |
Some additional debug info from my project (tested with sol v3.2.2):
Error message:
Code: Lua lua;
auto &state = *lua.state();
sol::environment env = state.globals();
env["func"] = [](Object *obj) { printf("Global state\n"); };
state.script("loadType('algine::Object') loadType('algine::Scene') function f(o) func(o) end", env);
if (auto res = env["f"].get<sol::function>()((algine::Scene*) this); !res.valid()) {
sol::error err = res;
printf("%s\n", err.what());
} Hope it will help to fix this issue |
Complete test case that reproduces the original issueSo, I continued my research regarding the original issue - and finally have found out all circumstances for the original issue aka "strange problem" to occur. Final results
DemoDemo and more detailed results can be found here: https://github.com/congard/sol2-issue-1532 |
Note: it is not a duplicate of #700
sol version: 3.3.0
Lua version: 5.4.4
Compiler:
Fedora 38 clang 16.0.0/ Windows 11 clang 16.0.0, target: x86_64-pc-windows-msvcComplete test case: #1532 (comment)
I've bumped into quite strange sol2 behavior, that looks quite similar to #700 except one important thing - I have explicitly provided base classes. So, here is some of my code:
Base class binding:
Derived class binding:
Then, I create a new environment:
Finally, I register the aforementioned types like this:
My Lua code looks like:
doSomethingWithObject
implementation:And I get the following error:
What's strange, to make it work as expected I just need to create a new usertype that inherits
algine::Object
:So, my first question is: what can be wrong with the snippets above? What's the possible problem with them? What potential problems do you see?
And my second question: is it safe to use
sol::table
instead ofsol::environment
in the bindings code?The text was updated successfully, but these errors were encountered: