gpt4 book ai didi

c++ - 使用可变参数模板从 Lua 函数回调 (C api) 中提取参数

转载 作者:行者123 更新时间:2023-11-28 08:07:11 25 4
gpt4 key购买 nike

我正在尝试编写一个类来提取从 Lua 函数调用(调用注册的 C 函数的 Lua 脚本)传递的参数,并将它们传递给注册的方法(我的代码片段中的 IDelegate),这样我就可以执行它并返回值。

假设我从 GameBoard 类注册了以下方法: long int GameBoard::testFunct(long int);作为 "GB:testFunction" 在 Lua 下使用以下代码:

luaL_newmetatable(mState, "GameBoard");
lua_pushstring(mState, "__index");
lua_pushvalue(mState, -2);
lua_settable(mState, -3);

lua_pushstring(mState,"testFunction");
hbt::IDelegate<I32,I32>* ideleg = new MethodDelegatePtr<GameBoard,I32,I32>( NULL, &GameBoard::testFunct); // will be deleted later
lua_pushlightuserdata (mState, (IDelegate<I32,I32>*)ideleg);
lua_pushcclosure(mState, LuaCall<I32,GameBoard,I32>::LuaCallback,1);
lua_settable(mState,-3);

(IDelegate & MethodDelegatePtr 用于注册方法、函数和仿函数,以便我稍后调用它们 )

然后是 LuaCall<I32,GameBoard,I32>::LuaCallback当我写 GB:testFunction(17); 时将被调用(以 Lua 堆栈作为参数)在 Lua 脚本中,然后注册的方法将被触发并返回等待的值。

如果我注册并调用一个没有任何参数的方法,它就会起作用。但是如果有任何参数等待为 long int GameBoard::testFunct(long int);做,然后我得到以下错误...

In static member function static Tr tUnpackLuaArgs<0u>::unpack(IDelegate*, lua_State*, ArgsValue ...) [with C = GameBoard, Tr = int, Args = {long int}, ArgsValue = {std::basic_string}, lua_State = lua_State]’:

instantiated from ‘static Tr tUnpackLuaArgs::unpack(IDelegate*, lua_State*, ArgsValue ...) [with C = GameBoard, Tr = int, Args = {long int}, ArgsValue = {}, unsigned int i = 1u, lua_State = lua_State]’

instantiated from ‘static int LuaCall::LuaCallback(lua_State*) [with C = GameBoard, Args = {long int}, lua_State = lua_State]’

error: no match for call to ‘(MethodDelegatePtr) (std::basic_string&)’

note: no known conversion for argument 1 from ‘std::basic_string’ to ‘long int&’


In static member function ‘static Tr tUnpackLuaArgs<0u>::unpack(IDelegate*, lua_State*, ArgsValue ...) [with C = GameBoard, Tr = int, Args = {long int}, ArgsValue = {bool}, lua_State = lua_State]’:

instantiated from ‘static Tr tUnpackLuaArgs::unpack(IDelegate*, lua_State*, ArgsValue ...) [with C = GameBoard, Tr = int, Args = {long int}, ArgsValue = {}, unsigned int i = 1u, lua_State = lua_State]’

instantiated from ‘static int LuaCall::LuaCallback(lua_State*) [with C = GameBoard, Args = {long int}, lua_State = lua_State]’

error: no match for call to ‘(MethodDelegatePtr) (bool&)’

note: no known conversion for argument 1 from ‘bool’ to ‘long int&’

我无法找到为什么 ArgsValue 试图传递 std::basic_string<char>bool当我注册等待 long int 的方法时... 它应该通过 long int .

这是我编写的用于提取来自 Lua 脚本函数调用的参数的类。

template< unsigned int i >
class tUnpackLuaArgs
{

public:
template< class C, class Tr, class... Args, class... ArgsValue >
static Tr unpack( IDelegate<C,Tr,Args...>* ideleg, lua_State *L, ArgsValue... argsVal)
{
int t = lua_type(L, i+1);

if( t == LUA_TNUMBER)
{
I32 tmpUint = lua_tonumber(L, i+1);
return tUnpackLuaArgs< i-1 >::unpack( ideleg, L, argsVal..., tmpUint);
}
else if( t == LUA_TSTRING)
{
std::string tmpStr = lua_tostring(L, i+1);
return tUnpackLuaArgs< i-1 >::unpack( ideleg, L, argsVal..., tmpStr);
}
else if( t == LUA_TBOOLEAN)
{
bool tmpBool = lua_toboolean(L, i+1);
return tUnpackLuaArgs< i-1 >::unpack( ideleg, L, argsVal..., tmpBool);
}
//etc.
}
};


template<>
class tUnpackLuaArgs<0>
{
public:
template< class C, class Tr, class... Args, class... ArgsValue >
static Tr unpack( IDelegate<C,Tr,Args...>* ideleg, lua_State *L, ArgsValue... argsVal)
{
//-- Execute the registered method using the LUA arguments
//-- and returns the returned value
return (*ideleg)( argsVal... );
}
};

下面是我如何使用它:

// Specialized template returning an integer
template <class C, class... Args>
struct LuaCall<int, C, Args...>
{
static int LuaCallback(lua_State *L)
{
//-- retrieve method "IDelegate" from Lua stack etc.
//-- then call tUnpackLuaArgs with the arguments to push the returned value onto the lua stack
lua_pushnumber(L, tUnpackLuaArgs< sizeof...(Args) >::unpack(funcPtr,L));
return 1;
}
};

确实,如果我删除 LUA_TSTRINGLUA_TBOOLEAN来自 unpack 中的 if/else函数,它确实可以编译并且工作正常。

最佳答案

实际上,如果您的代码包含例如tUnpackLuaArgs<1>::unpack , 然后是 unpack 的正文将热切地实例化所有可能性(因为根据 Lua 堆栈上的参数类型,它们都可能在运行时到达)。

这包括例如tUnpackLuaArgs<0>::apply<C, Tr, Args..., std::string> ,这意味着您会收到 Args 时出现的错误是例如long intstd::string无法转换为 long int const&operator()IDelegate期待。

您实际上并不需要所有这些可能性:您已经知道您期望什么(例如 long int 在您的情况下)。提取 std::string当你想要 long int没有用。因此,您应该尝试从 Lua 堆栈中提取您期望的内容(如果转换不起作用,您可能会出错,直到运行时才知道)。

关于c++ - 使用可变参数模板从 Lua 函数回调 (C api) 中提取参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10084290/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com