iOS 5.x에서 게임의 루아 (5.2) 스크립팅을 허용하기 위해 라이브러리 작업을하고 있습니다. 클래스를 만들고 바인딩을 추가하여 Lua를 만들고 액세스 할 수있게했습니다. 루아에서 호출 C의 초기화 방법에 대하여 주어진다userdata에서 Objective C/C로 루아 전역 만들기
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;
}
이것은 다양한 방법에 대한 액세스를 제공하는 다른 설정 메타 테이블을 할당한다. 또한 스크립트 코드가 개체에 특성을 할당 할 수 있도록 테이블을 사용자 값으로 연결합니다.
나는 문제없이 루아 스크립트에서 이러한 개체를 만들 수 있습니다
다음 objectTouchedrequire "gemini"
x = gemini.new()
x:addEventListener("touch", objectTouched)
는 터치 이벤트를 처리 다른 곳에서 정의 루아 방법입니다. 여기 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:addEventListener("enterFrame", enterFrame)
결과와 같은 스크립트에서이 변수에 액세스하려고 :
attempt to index global 'Runtime' (a userdata value)
는 그것은 유저 데이터 값이지만,이 내가 하나를 만들 때 중요하지 않는 것 루아에서 직접. 메타 바인딩은 메서드와 메타 메서드에 대한 액세스를 제공합니다. 다시 말하지만, 객체가 루아에서 생성 된 경우에는 올바르게 동작합니다.
여기에서 내가 뭘 잘못하고 있는지 또는 userdata에서 글로벌하게 만드는 올바른 방법은 무엇입니까? ? 보여주지 (이 코드는 함수의 라이브러리를 등록
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;
}
: GEMINI_OBJECT_LUA_KEY에 대한 혼란에 대한 아래의 의견을 바탕으로 편집
, 나는 실제로 바인딩에서 사용되는 코드를 나열 것이라고 생각 여기에서) GeminiObjects
에 대한 방법과 메타 메소드를 제공합니다. luaL_newmetatable
을 호출하면 새 메타 테이블이 만들어지고 레지스트리에 키 GEMINI_OBJECT_LUA_KEY
과 연결됩니다. GEMINI_OBJECT_LUA_KEY
은 헤더에 정의 된 고유 한 문자열입니다. luaL_setfuncs
은 실제로 함수 포인터를 메타 테이블에 추가하여 객체의 메소드로 사용할 수 있도록합니다.
정말 개체 설정 도구를 함수로 분해해야합니다. 복사 및 붙여 넣기 코딩이 좋지 않습니다. 또한'GEMINI_OBJECT_LUA_KEY'는 어떻게 작동합니까? 항상 같은 장소에 있지는 않습니다. 스택에 푸시하지 않으면 (그리고 심지어 그렇다고해도 반드시 * 생각한 위치에 있지는 않습니다). –
그것에 대해 생각한 후에,이 신비한'GEMINI_OBJECT_LUA_KEY' 건과 관련이 있다고 생각합니다. 당신은 잘못된 테이블을 얻었고 사용자 데이터의 메타 테이블에'nil' 값을 설정 한 것 같습니다. –
@ NicolBolas 의견을 보내 주셔서 감사합니다.하지만 내 코드가 기능 상에 없다고 생각하는 이유가 확실하지 않습니다. 분명히 여기에 두 개의 함수 인'newGeminiObject'가 루아에 의해 호출 된 C 함수의 표준 프로토 타입 다음에 오는 C 함수와'Runtime' 객체의 단일 인스턴스를 생성하는 Objective C 함수 인'addRuntimeObject'를 나열했습니다. 또한 잘라 내기 및 붙여 넣기 코드가 없으므로 그 이유를 알 수 없습니다. 'GEMINI_OBJECT_LUA_KEY'와 관련하여, 이것은이 객체 유형에 대한 메타 테이블을 설정할 때 별도의 메소드에서 사용되는 상수입니다. 이것은 표준 물건입니다. – James