Как проверить, имеет ли параметр, передаваемый в Lua, пользовательский тип?

#c #scripting #lua #ogre

#c #сценарии #lua #ogre

Вопрос:

Я реализую сценарии для своего приложения на основе Ogre3d, используя Lua, и я столкнулся с проблемой проверки того, имеет ли параметр, передаваемый в функцию, определенный тип — Ogre::SceneNode *. Кто-нибудь знает, как я могу это сделать?

Есть несколько базовых функций Lua, выполняющих это для встроенных типов, таких как int или string, например

if(lua_isnumber(L,1))
{...}

но я не знаю, как это сделать с пользовательскими типами.

Ответ №1:

Если вы организуете для каждого из ваших userdata параметров определенного типа совместное использование метатаблицы, то вы можете использовать luaL_checkudata для подтверждения их типа. Обычно библиотека помечает и идентифицирует данные, которые она создает.

Вот несколько функций, которые создают и проверяют пользовательские данные, используя этот метод:

 static decContext *ldn_check_context (lua_State *L, int index)
{
    decContext *dc = (decContext *)luaL_checkudata (L, index, dn_context_meta);
    if (dc == NULL) luaL_argerror (L, index, "decNumber bad context");
    return dc; /* leaves context on Lua stack */
}

static decContext *ldn_make_context (lua_State *L)
{
    decContext *dc = (decContext *)lua_newuserdata(L, sizeof(decContext));
    luaL_getmetatable (L, dn_context_meta);
    lua_setmetatable (L, -2); /* set metatable */
    return dc;  /* leaves context on Lua stack */
}
  

Метатаблица была создана с

 const char *dn_context_meta = "decNumber_CoNTeXT_MeTA";
luaL_newmetatable (L, dn_context_meta);
  

Ответ №2:

Я думаю lua_isuserdata(L, yourParam) ?

Было бы логично.

Комментарии:

1. Да, наряду с lua_islightuserdata()

2. хм, да, это кажется правильным, но как я могу проверить, относится ли это к этому конкретному типу данных и существует ли этот Ogre::SceneNode?

3. @Heandel Хорошо, теперь я понял это: Ogre::SceneNode* sceneNode = dynamic_cast<Ogre::SceneNode*>( lua_touserdata(L, 2) ); но я не могу этого сделать, потому что ошибка C2681: ‘void *’: недопустимый тип выражения для dynamic_cast

4. @Heandel : Что вы имеете в виду под этим? Сейчас я сделал что-то подобное: sceneNode = (Ogre::SceneNode*)( lua_touserdata(L, 2) ); но в любом случае lua_islightuserdata(L,2) or lua_isuserdata(L,2) возвращает false . Очевидно, что он может быть другого типа, но не должен.

5. @Haendel: Я думаю, мне придется реализовать гораздо больше, чем я думал. проблема в том, что я хочу запустить в . файловая функция lua, которая принимает в качестве аргумента Ogre::SceneNode* но могу ли я просто поместить foo(mNode) , где mNode — переменная из класса c ? Я сомневаюсь в этом прямо сейчас:/ поэтому для этого мне придется написать функцию, которая возвращает данные пользовательского типа. как я могу это сделать? Я обнаружил, что есть некоторые проблемы с lua_pushuserdata() .