Создание Lua-глобалов в Objective C / C из userdata

Я работаю над библиотекой, чтобы разрешить Lua (5.2) скрипты игр в iOS 5.x. Я создал класс и добавил привязки, чтобы он можно было создать и получить доступ к форме Lua. Метод инициализатора C, вызванный из Lua, приведен ниже:

static int newGeminiObject(lua_State *L){ GeminiObject *go = [[GeminiObject alloc] initWithLuaState:L]; GeminiObject **lgo = (GeminiObject **)lua_newuserdata(L, sizeof(GeminiObject *)); *lgo = go; luaL_getmetatable(L, GEMINI_OBJECT_LUA_KEY); lua_setmetatable(L, -2); lua_newtable(L); lua_setuservalue(L, -2); NSLog(@"New GeminiObject created"); // add this new object to the globall list of objects [[Gemini shared].geminiObjects addObject:go]; return 1; } 

Это назначает метатет, который настроен в другом месте для обеспечения доступа к различным методам. Кроме того, он прикрепляет таблицу как служебную информацию, позволяющую сценарию сценария назначать атрибуты объектам.

Я могу создать эти объекты в сценариях Lua без проблем:

 require "gemini" x = gemini.new() x:addEventListener("touch", objectTouched) 

Здесь objectTouched – метод aa Lua, определенный в другом месте, который обрабатывает событие касания. Здесь addEventListener связывает его, чтобы touch событий.

Эти объекты работают очень хорошо. Однако, когда я пытаюсь создать один из C, у меня возникают проблемы. Я могу создать объект, но пытаюсь назначить его глобальному, а затем вызывать его в скрипте.

Выполняется следующий код C

 -(void) addRuntimeObject { GeminiObject *rt = [[GeminiObject alloc] initWithLuaState:L]; GeminiObject **lruntime = (GeminiObject **)lua_newuserdata(L, sizeof(GeminiObject *)); *lruntime = rt; // set the metatable - effectively declaring the type for this object luaL_getmetatable(L, GEMINI_OBJECT_LUA_KEY); lua_setmetatable(L, -2); // add a table to hold anything the user wants to add lua_newtable(L); lua_setuservalue(L, -2); // create an entry in the global table lua_setglobal(L, "Runtime"); // empty the stack lua_pop(L, lua_gettop(L)); } 

Это должно определить глобальное имя «Runtime». Пытаясь получить доступ к этой переменной из сценария, подобного этому

 Runtime:addEventListener("enterFrame", enterFrame) 

Результаты со следующей ошибкой:

attempt to index global 'Runtime' (a userdata value)

Это значение userdata, но это не кажется важным, когда я создаю его в Lua напрямую. Метатизируемое связывание обеспечивает доступ к методам и метаметодам. Опять же, это отлично работает, если объект создан из Lua, а не когда он создан на C.

Любые идеи относительно того, что я делаю неправильно здесь, или то, что правильный способ сделать глобальным из userdata?

РЕДАКТИРОВАТЬ

Основываясь на комментариях ниже относительно путаницы в отношении GEMINI_OBJECT_LUA_KEY, я думал, что перечислил код, который фактически используется в привязке:

 static const struct luaL_Reg geminiObjectLib_f [] = { {"new", newGeminiObject}, {NULL, NULL} }; static const struct luaL_Reg geminiObjectLib_m [] = { {"addEventListener", addEventListener}, {"__gc", geminiObjectGC}, {"__index", l_irc_index}, {"__newindex", l_irc_newindex}, {NULL, NULL} }; int luaopen_geminiObjectLib (lua_State *L){ // create the metatable and put it into the registry luaL_newmetatable(L, GEMINI_OBJECT_LUA_KEY); lua_pushvalue(L, -1); // duplicates the metatable luaL_setfuncs(L, geminiObjectLib_m, 0); // create a table/library to hold the functions luaL_newlib(L, geminiObjectLib_f); NSLog(@"gemini lib opened"); return 1; } 

Этот код регистрирует библиотеку функций (не показаны здесь), которые предоставляют методы и метаметоды для GeminiObjects . Вызов luaL_newmetatable создает новый метатебель и связывает его в реестре с ключом GEMINI_OBJECT_LUA_KEY . GEMINI_OBJECT_LUA_KEY – это просто уникальная строка, определенная в заголовке. luaL_setfuncs фактически добавляет указатели на функции к метатегам, делая их доступными как методы объектов.

One Solution collect form web for “Создание Lua-глобалов в Objective C / C из userdata”

В случае, если кто-то все еще интересуется, я получил ответ на свой вопрос от добрых людей в списке рассылки Lua. Проблема здесь в том, что функция привязки библиотеки luaopen_geminiObjectLib не вызывается перед моим вызовом addRuntimeObject .

Поскольку iOS не поддерживает динамические библиотеки, я добавил свои библиотеки в статически, добавив указатели на них в массив linit.c в linit.c источника Lua. К сожалению, библиотеки, добавленные таким образом, не загружаются до тех пор, пока не require('libname') в сценарии Lua. Поскольку я вызывал свой метод addRuntimeObject до выполнения сценария Lua, библиотека еще не была загружена.

Решение состоит в том, чтобы добавить указатель на luaopen_geminiObjectLib в массив loadedlibs в том же файле linit.c . Это приводит к загрузке библиотеки при запуске Lua без необходимости использования сценариев.

Interesting Posts

iPhone – GestureRecognizer иногда не срабатывает?

Обеспечьте гладкую прокрутку для Photo Grid с тысячами изображений с диска

Анимация скрытого свойства на UILabels в UIStackView вызывает различные анимации

автоматически созданный подкласс NSManagedObject для логического атрибута вызывает предупреждение

Я хочу перемещать тело спрайта при обнаружении точки касания

Интерфейс контактов эквивалентен ABAddressBook.ABAddressBookRegisterExternalChangeCallback

iOS9 – Работа с Instagram (w / hooks) не работает

Возможно ли выполнить Popover Segue вручную (из динамической ячейки UITableView)?

CoreBluetooth backgound – Как восстановить ресурсы центрального менеджера в appdelegate?

Возможно ли обновить строки локализованного раскадровки?

Как добавить subview над клавиатурой в monotouch / Xamarin.Ios?

Могу ли я использовать автозапуск, чтобы обеспечить различные ограничения для пейзажной и портретной ориентации?

Быстрая инициализация объектов (метод фабрики классов, инициализация по умолчанию, удобство инициализации)

Приложение iPad перенесено на другой аккаунт, чтобы сохранить доступ к брелокам

Ошибка связи: неизвестный символ опции `X 'в: -Xlinker

PhoneC: Разработка iOS проста с помощью XCode, Swift3, UITableView, cocatouch, давайте создадим приложения для iPhone, iPad и Macbook.