2009-04-06 2 views
0

В функции C, вызванной из моего сценария Lua, я использую luaL_ref для хранения ссылки на функцию. Однако, если я попытаюсь использовать возвращаемый целочисленный индекс для извлечения этой функции из другого потока, который не является производным от одного и того же состояния, все, что я возвращаю, это nil. Вот самый простой пример, который, кажется, чтобы продемонстрировать это:Lua реестра не видно из новых состояний

// Assumes a valid lua_State pL, with a function on top of the stack 
int nFunctionRef = luaL_ref(pL, LUA_REGISTRYINDEX); 

// Create a new state 
lua_State* pL2 = luaL_newstate(); 
lua_rawgeti(pL2, LUA_REGISTRYINDEX, nFunctionRef); 
const char* szType = luaL_typename(pL2, -1); 

Я нахожу, что szType затем содержит значение «ноль».

Насколько я понимаю, реестр был глобально распространен между всеми C-кодом, так что может кто-нибудь объяснить, почему это не работает?

Если реестр не разделяется глобально таким образом, как я могу получить доступ к моим значениям, как мне нужно, из другого сценария?

+0

Удален тег 'registry', поскольку он, очевидно, относится к реестру Windows. – akauppi

ответ

6

Реестр является обычной таблицей в состоянии Lua, поэтому два несвязанных состояния Lua не могут получить доступ к одному и тому же реестру.

Как говорит Kknd, вы должны будете предоставить свой собственный механизм. Общим трюком является создание дополнительного состояния, которое не выполняет никакого кода, оно используется только как хранилище. В вашем случае вы будете использовать этот реестр дополнительного состояния из своего C-кода. К сожалению, нет никакого способа скопировать произвольные значения между двумя состояниями, поэтому вам придется развернуть любые таблицы.

Функции копирования особенно сложны, если вы используете реестр для этого, вы можете отслеживать, какое состояние вы использовали для его хранения, и выполнять его в исходном состоянии, эффективно превращая его в кросс- вместо вызова функции.

2

luaL_newstate() создает другое разделенное состояние, как говорится в названии. Реестр разделяется только между «потоками», созданными с помощью lua_newthread (parent_state);

Редактировать, чтобы соответствовать вопросу редактирования:

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

2

Чтобы использовать несколько юниоров Lua (штатов), вы можете найти Lua Lanes. Существует также грубое comparison многоуровневых решений Lua.

Переулки фактически предоставляют «скрытое состояние», которое упоминает Хавьер. Он также обрабатывает блокировки, необходимые для доступа к таким общим данным, и возможность ждать, пока такие данные изменятся. И он копирует все, что можно скопировать (включая функции и блокировки) между состояниями вашего приложения и скрытым состоянием.