Closed osaengine closed 7 years ago
Hi! I need a small repro. Can you assist me with that?
Although, given the stacktrace, I suppose you're trying to pass a member function pointer. I'm not aware of a technical solution in the library that would allow such. If that is the case it would be wise to explecitly disallow it though through compile time checks.
Yes, I try to invoke method of some class. Seems it is impossible in Luabind. Or I've missed something?
The problem is not to invoke a method of some class, but passing a member function pointer, I believe. We'd need to add overloads/converters and add each different signature of member function pointer in use to a true value type, so it can be stored correctly and "decoded" again. Member function pointers cannot be treated like ordinary pointers. But maybe I'm totally mistaken... I'm just thinking out loud.
Actually the issue appears while regular method call. Like
call_function
So the issue not in function pointer. Issue with instance of Lua class.
Well, this would qualify as bug.
The only code of you I see is "call_function
luabind-deboostified passes the free function tests contained. If you can provide a minimal example that fails, I could do more.
Did a migration on deboostified. Looks the issue still is. Here is the latest stack trace:
System.Runtime.InteropServices.SEHException (0x80004005): External component has thrown an exception.
at _CxxThrowException(Void* , _s__ThrowInfo* )
at luabind.detail.call_error(lua_State* L) in c:\luabind\detail\call_shared.hpp:line 32
at luabind.detail.call_function_struct<luabind::adl::object,luabind::meta::type_list<>,luabind::meta::index_list<1>,1,&luabind::detail::pcall,0>.call<char const (&)[6]>(object* , lua_State* L, $ArrayType$$$BY05$$CBD* <args_0>) in c:\luabind\detail\call_function.hpp:line 125
at luabind.call_pushed_function<class luabind::adl::object,struct luabind::meta::type_list<>,char const (&)[6]>(object* , lua_State* L, $ArrayType$$$BY05$$CBD* <args_0>) in c:\uabind\detail\call_function.hpp:line 147
at luabind.call_function<class luabind::adl::object,struct luabind::meta::type_list<>,char const (&)[6]>(object* , object* obj, $ArrayType$$$BY05$$CBD* <args_0>)
Line is
auto state = call_function
Lua's equivalent (that is works fine):
state1 = CreateDataSource("TQBR", "LKOH", INTERVAL_M1); --state1:SetUpdateCallback(NewCandle); state1:Close();
call_function expects a lua state or a callable "function" object as its first argument, neither of which is the case for your call. Maybe try call_function(state["Close"])? I did not test it, but it should push a lua function and call it.
And you could pass in a std::function as a callback function, for your seconds problem.
call_function(state["Close"]) helped! Thanks.
Could you please provide an example? My code below. What I should to change?
bool result = call_function
might work depending on your circumstances.
I'm thinking about maybe adding a convenience syntax for member function calls should be added, in case I did not overlook anything that is in place already.
ermm, it'd be std::bind(&DataHandler::OnUpdate, this, std::placeholders::_1) or something... I'm not close to a compiler currently^^
Wrote following, but issue still is:
std::function<void(int)> handler = std::bind(&DataHandler::OnUpdate, this, std::placeholders::_1);
Also remember that the lua function will probably expect the "state" as first arg and only then the callback, if it is a "well behaved" member function.
or alternatively with lambdas
std::function<void(int)> = [&](int foo) { OnUpdate(foo); }
Same issue. Stack trace:
at _CxxThrowException(Void , _s__ThrowInfo )
at luabind.detail.make_pointer_instance<class std::function<void cdecl(int)> >(lua_State L, function<void __cdecl(int)>* p) in c:\luabind\detail\make_instance.hpp:line 72
at luabind.detail.make_pointee_instance<class std::function<void cdecl(int)> &>(lua_State L, function<void __cdecl(int)> x, integral_constant<bool\,0> unnamed002, integral_constant<bool\,0> unnamed003) in c:\luabind\detail\conversion_policies\conversion_base.hpp:line 64
at luabind.detail.make_pointee_instance<class std::function<void cdecl(int)> &,struct std::integral_constant<bool,0> >(lua_State L, function<void __cdecl(int)> x, integral_constant<bool\,0> unnamed002) in c:\luabind\detail\conversion_policies\conversion_base.hpp:line 70
at luabind.detail.ref_converter.to_lua<class std::function<void cdecl(int)> >(ref_converter , lua_State L, function<void cdecl(int)> ref) in c:\luabind\detail\conversion_policies\reference_converter.hpp:line 45
at luabind.detail.push_arguments<struct luabind::meta::type_list<>,1,class std::function<void __cdecl(int)> &>(lua_State L, function<void cdecl(int)> arg0) in c:\luabind\detail\call_function.hpp:line 51
at luabind.detail.call_function_struct<bool,luabind::meta::type_list<>,luabind::meta::index_list<1>,1,&luabind::detail::pcall,0>.call<class std::function<void __cdecl(int)> &>(lua_State L, function<void cdecl(int)>
Hrmm, it should normally trigger the std::function converter found in function_converter.hpp
Hrmm, I see, it values the reference over the function type and so misses the converter. That's a bug.
Can you try replacing the line 53 in detail/conversion_policies/function_converter.hpp from
struct default_converter<F, typename std::enable_if<detail::is_function<F>::value>::type>
to
struct default_converter<F, typename std::enable_if<detail::is_function<typename std::remove_reference<F>::type>::value>::type>
?
That would only be a short term fix though... Ideally all the calls should "semantically" take by value, even if they physically take by ref or rvale ref, with the exception of std::reference_wrapper ... I don't know if I can make that quickly though.
It's helped but I still some doubt Luabind can work properly with Lua instances. All other methods throws an errors while invoke from C++. From Lua - OK.
I can send my proj to reproduce but I wanna send it via email (or other non public way).
Well, it would be nice to know the reason for the exceptions, not just that they happen. Did you pass in the object as first argument to the lua methods?
I call methods like you pointed (get 0x80004005 error):
auto size = call_function
In Lua the same (works OK):
local size = state:Size();
at _CxxThrowException(Void , _s__ThrowInfo )
at luabind.detail.cast_error
lua methods take the "this" as first argument.
some_object:method(blah)
is short for some_object.method(some_object, blah)
.
Please pass in the object as first argument to the method as in
call_function(state["Size"], state)
Thanks a lot. Looks all works cool. Will wait you fix with function_converter
Well, and now that I had time to take a look, I found "call_member" inside call_member.hpp, which does exactly the convenience syntax without the proxy object clutter etc..
Not sure I've got your message. If something need for regression test - I am in.
Have a small issue with nil values. What the conversion should to use with lua objects? With 0 not work, object always not null:
if (state == 0 || !state.is_valid())
{
// never happen
}
-