Skip to content
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

set_function with __stdcall under widnows #463

Closed
horatii opened this issue Jul 31, 2017 · 17 comments

Comments

@horatii
Copy link

@horatii horatii commented Jul 31, 2017

lua.set_function("MessageBoxA", &MessageBoxA);

@ThePhD ThePhD self-assigned this Jul 31, 2017
@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Jul 31, 2017

MessageBoxA is overloaded. You need to A) select the right overload (see resolve) and then B) bind it like you are now. If you want to make it simple, you can use a lambda:

lua.set_function("MessageBoxA", [&hwnd](const char* caption, const char* message) {
      MessageBoxA(hwnd, caption, message, MB_OK);
})l

You can customize it to behave more how you would like. Best of luck!

@ThePhD ThePhD closed this Jul 31, 2017
@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 1, 2017

The issue is HWND type not recognized by sol2.

void __stdcall Message(HWND hwnd)
{

}

lua.set_function("Message", &Message);

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 1, 2017

Okay, what's the compiler error?

@ThePhD ThePhD reopened this Aug 1, 2017
@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 1, 2017

As a side note, the following code works perfectly:

void __stdcall Message(HWND hwnd) {
	MessageBoxA(hwnd, "bark", "doggo", 0);
}

int main() {
	HWND hwnd = ...; // CreateWindowA( ... ) or whatever works for your machine

	sol::state lua;

	lua.set_function("Message", &Message);
	lua["hwnd"] = hwnd;
	lua.script("Message(hwnd)");
}
@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 1, 2017

void Message2(HWND ptr)
{

}


void __stdcall Message3(HWND ptr)
{

}

''''
void LuaScript(void)
{
sol::state lua;
lua.open_libraries();
lua.set_function("Message2", &Message2); // ok
lua.set_function("Message3", &Message3); // error
}
'''

##Error

1>------ Build started: Project: animate, Configuration: Debug Win32 ------
1>  LuaScript.cpp
1>e:\workspace\marie\3rdparty\sol2\sol.hpp(8236): error C2198: 'void (__stdcall *)(HWND)': too few arguments for call
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(8242): note: see reference to function template instantiation 'decltype(auto) sol::wrapper<void (__stdcall *)(HWND),void>::call<>(F &)' being compiled
1>          with
1>          [
1>              F=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(7966): note: see reference to function template instantiation 'decltype(auto) sol::wrapper<void (__stdcall *)(HWND),void>::caller::operator ()<>(F &) const' being compiled
1>          with
1>          [
1>              F=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(7992): note: see reference to function template instantiation 'decltype(auto) sol::stack::stack_detail::evaluator::eval<_Ty,void(__stdcall *&)(HWND)>(sol::types<>,std::integer_sequence<std::size_t>,lua_State *,int,sol::stack::record &,Fx &&,void (__stdcall *&)(HWND))' being compiled
1>          with
1>          [
1>              _Ty=caller,
1>              Fx=caller
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(8016): note: see reference to function template instantiation 'void sol::stack::stack_detail::call<false,,,_Ty,void(__stdcall *&)(HWND)>(sol::types<R>,sol::types<>,std::integer_sequence<std::size_t>,lua_State *,int,Fx &&,void (__stdcall *&)(HWND))' being compiled
1>          with
1>          [
1>              _Ty=caller,
1>              R=void,
1>              Fx=caller
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(8036): note: see reference to function template instantiation 'void sol::stack::call<false,,_Ty,void(__stdcall *&)(HWND)>(sol::types<R>,sol::types<>,lua_State *,int,Fx &&,void (__stdcall *&)(HWND))' being compiled
1>          with
1>          [
1>              _Ty=caller,
1>              R=void,
1>              Fx=caller
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(8802): note: see reference to function template instantiation 'int sol::stack::call_into_lua<false,,caller,void(__stdcall *&)(HWND)>(sol::types<R>,sol::types<>,lua_State *,int,Fx &&,void (__stdcall *&)(HWND))' being compiled
1>          with
1>          [
1>              R=void,
1>              Fx=caller
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(9250): note: see reference to function template instantiation 'int sol::call_detail::agnostic_lua_call_wrapper<F,true,false,false,0,void>::call<void(__stdcall *&)(HWND),>(lua_State *,Fx)' being compiled
1>          with
1>          [
1>              F=void (__stdcall *)(HWND),
1>              Fx=void (__stdcall *&)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(9250): note: see reference to function template instantiation 'int sol::call_detail::agnostic_lua_call_wrapper<F,true,false,false,0,void>::call<void(__stdcall *&)(HWND),>(lua_State *,Fx)' being compiled
1>          with
1>          [
1>              F=void (__stdcall *)(HWND),
1>              Fx=void (__stdcall *&)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(9422): note: see reference to function template instantiation 'int sol::call_detail::call_wrapped<void,true,false,0,void(__stdcall *&)(HWND),>(lua_State *,Fx)' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *&)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(9419): note: while compiling class template member function 'int sol::function_detail::upvalue_free_function<Fx>::real_call(lua_State *) noexcept(false)'
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(10016): note: see reference to class template instantiation 'sol::function_detail::upvalue_free_function<Fx>' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(10036): note: see reference to function template instantiation 'void sol::stack::pusher<sol::function_sig<>,void>::select_function<void(__stdcall *)(HWND),>(std::true_type,lua_State *,Fx &&)' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(10036): note: see reference to function template instantiation 'void sol::stack::pusher<sol::function_sig<>,void>::select_function<void(__stdcall *)(HWND),>(std::true_type,lua_State *,Fx &&)' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(10057): note: see reference to function template instantiation 'void sol::stack::pusher<sol::function_sig<>,void>::select<void(__stdcall *)(HWND),,sol::meta::enable_t::_>(lua_State *,Fx &&)' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
1>  e:\workspace\marie\3rdparty\sol2\sol.hpp(10057): note: see reference to function template instantiation 'void sol::stack::pusher<sol::function_sig<>,void>::select<void(__stdcall *)(HWND),,sol::meta::enable_t::_>(lua_State *,Fx &&)' being compiled
1>          with
1>          [
1>              Fx=void (__stdcall *)(HWND)
1>          ]
....
@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 1, 2017

sol2_issues

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 1, 2017

No repro on my machine: seems okay

What version of Visual Studio are you using?

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 1, 2017

Found the problem: this error only triggers for 32-bit builds. I was building for 64-bit. I have no idea why this happens...

@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 1, 2017

this issuse look like trigger by __stdcall

@horatii

This comment has been minimized.

@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 1, 2017

This fine

sol2_issues

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 1, 2017

I will add this workaround to the documentation. Thanks for finding the answer.

@ThePhD ThePhD added this to the Documentation milestone Aug 1, 2017
@ThePhD

This comment has been minimized.

@ThePhD ThePhD closed this Aug 5, 2017
@horatii

This comment has been minimized.

Copy link
Author

@horatii horatii commented Aug 9, 2017

template <typename T>
struct caller;

//
// call wrapper
//
template <typename Rx, typename ...Args>
struct caller<Rx(Args...)>
{
	typedef Rx _result_type;
	typedef Rx(*_function_type)(Args...);
	
	caller (_function_type function)
		: _function(function)
	{
	}

	_result_type operator()(Args&&... args)
	{
		_result_type arr[1 + sizeof ...(args)] = { 0, std::forward<Args>(args)... };
		return (*_function)(std::forward<Args>(args)...);
	}

	_function_type _function;
};

//
// call wrapper
//
template <typename Rx, typename ...Args>
struct caller<Rx __stdcall (Args...)>
{
	typedef Rx _result_type;
	typedef Rx(__stdcall *_function_type)(Args...);

	caller(_function_type function)
		: _function(function)
	{
	}

	_result_type operator()(Args&&... args)
	{
		_result_type arr[1 + sizeof ...(args)] = { 0, std::forward<Args>(args)... };
		return (*_function)(std::forward<Args>(args)...);
	}

	_function_type _function;
};

int __stdcall _cc(int, char)
{
	return 0;
}

int _cc2(int, char)
{
	return 0;
}

int main(int argc, char* argv[])
{

	std::string str = u8"";
	std::u16string _2 = u"";
	std::wstring _3 = L"";
	std::u32string _1 = U"123";

	caller<int __stdcall (int, char)> _c(&_cc);
	_c(2, 2);

	caller<int (int, char)> _c2(&_cc2);
	_c2(2, 2);

	return 0;
}
@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 9, 2017

_result_type arr[1 + sizeof ...(args)] = { 0, std::forward<Args>(args)... };

Why are the arguments forwarded into an array...?

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 10, 2017

I added specializations for this that trigger specifically under MSVC and x86, since x64 seems fine. I also added tests to make sure this never happens again.

Thanks for bringing this to my attention and telling me about the fix. I appreciate it!

@ThePhD

This comment has been minimized.

Copy link
Owner

@ThePhD ThePhD commented Aug 11, 2017

Incorporated formally into latest release: https://github.com/ThePhD/sol2/releases/tag/v2.18.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.