2015-02-07 4 views
1

Я разрабатываю приложение iOS для запуска скриптов Lua, я могу легко интегрировать базу lua с поддержкой CocoaPods, но как добавить в нее библиотеку LuaSocket? LuaSocket содержит некоторые C и некоторые файлы Lua, у кого есть идеи? Спасибо!Как использовать LuaSocket в приложении iOS?

ответ

1

Я использовал 2.0.2 версию LuaSocket и 5.1 для Lua. После изменения некоторых файлов [Неизвестное имя типа 'luaL_reg'; вы имели в виду «luaL_Reg»? ] Я смог скомпилировать. Также удалены файлы wsocket (.h & .c). Поэтому он компилируется. После некоторого поиска я обнаружил, что исходный код Cocos2d-x (3.0.4) использует папку luasocket (и имеет liblua.a). Удаленные снова файлы wsocket затем компилируются без ошибок. Я использовал

-(void)addBundlePathToLuaState:(lua_State*)L 
    { 
    lua_getglobal(L, "package"); 
    lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1) 

    const char* current_path_const = lua_tostring(L, -1); // grab path string from top of stack 
    NSString* current_path = [NSString stringWithFormat:@"%s;%@/?.lua", current_path_const, [[NSBundle mainBundle]resourcePath]]; 

    lua_pop(L, 1); // get rid of the string on the stack we just pushed on line 5 
    lua_pushstring(L, [current_path UTF8String]); // push the new one 
    NSLog(@"path current %s", [current_path UTF8String]); 
    lua_setfield(L, -2, "path"); // set the field "path" in table at -2 with value at top of stack 
    lua_pop(L, 1); // get rid of package table from top of stack 
    } 

и

int status; 
    lua_State *La; 
    La = luaL_newstate(); 
    NSBundle* myBundle = [NSBundle mainBundle]; 
    NSString* myImage = [myBundle pathForResource:@"a" ofType:@"lua"]; 
    const char *stringAsChar = [myImage cStringUsingEncoding:[NSString defaultCStringEncoding]]; 
    NSLog(@"mypath %s", stringAsChar); 
    luaL_openlibs(La); /* Load Lua libraries */ 
/* Load the file containing the script we are going to run */ 
    status = luaL_loadfile(La, stringAsChar); 
    NSString *luaFilePath = [[NSBundle mainBundle] pathForResource:@"a" ofType:@"lua"]; 
    [self addBundlePathToLuaState:La]; 

Мой сценарий использовать локальный сокет = требуется ("розетка"), но проблема в том, что не может найти ядро ​​socket.lua: 13: модуль 'socket.core' не найдено: нет поля package.preload [ «socket.core»]

Так что я не думаю, что вы можете получить успех в ближайшее время :)

3

С прошивкой 8 позволяет динамические структуры (библиотеки) там ма y более элегантный подход, но следующие работы с Lua 5.2.3 (, так как вы используете Cocoapods, а 5.2.3 - это версия, которую Cocoapod поставляет) и LuaSocket 3.0-rc1.

ЗАМЕЧАНИЕ, что я на самом деле не использую Cocoapod; включая Lua в вашем проекте iOS, достаточно просто, что я считаю, что это не стоит использовать Cocoapods. YMMV. Возможно, вам придется внести несколько изменений в то, что я опишу ниже из-за различий в пути.

  1. Создать новый IOS 'Single View' проекта
  2. Создайте группу с именем Lua в проекте штурмана XCode в
  3. Скопируйте все файлы (кроме lua.c, luac.c, lua.hpp и Makefile) из каталог src в Lua загрузить в эту группу
  4. Создать группу под названием LuaSocket в проекте штурмана XCode в
  5. Скопируйте все файлы (кроме Makefile, wsocket.c, wsocket.h) из каталога src в LuaSockets загрузить в этот группа
  6. Добавьте строку #import "luasocket.h" в файл serial.h в источнике LuaSocket

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

Во-первых, мы собираемся изменить luaL_openlibs так, чтобы он инициализировал код C LuaSocket следующим образом.

В источнике Lua найдите файл linit.с и изменить

static const luaL_Reg loadedlibs[] = { 
    {"_G", luaopen_base}, 
    {LUA_LOADLIBNAME, luaopen_package}, 
    {LUA_COLIBNAME, luaopen_coroutine}, 
    {LUA_TABLIBNAME, luaopen_table}, 
    {LUA_IOLIBNAME, luaopen_io}, 
    {LUA_OSLIBNAME, luaopen_os}, 
    {LUA_STRLIBNAME, luaopen_string}, 
    {LUA_BITLIBNAME, luaopen_bit32}, 
    {LUA_MATHLIBNAME, luaopen_math}, 
    {LUA_DBLIBNAME, luaopen_debug}, 
    {NULL, NULL} 
}; 

в

{"_G", luaopen_base}, 
    {LUA_LOADLIBNAME, luaopen_package}, 
    {LUA_COLIBNAME, luaopen_coroutine}, 
    {LUA_TABLIBNAME, luaopen_table}, 
    {LUA_IOLIBNAME, luaopen_io}, 
    {LUA_OSLIBNAME, luaopen_os}, 
    {LUA_STRLIBNAME, luaopen_string}, 
    {LUA_BITLIBNAME, luaopen_bit32}, 
    {LUA_MATHLIBNAME, luaopen_math}, 
    {LUA_DBLIBNAME, luaopen_debug}, 
    {"socket", luaopen_socket_core}, 
    {"mime", luaopen_mime_core}, 
    {NULL, NULL} 
}; 

Вам нужно добавить #include "luasocket.h" и #include "mime.h" в верхней части linit.c.

Есть еще несколько функций C, которые вы хотите добавить в этот список, например luaopen_socket_unix, но я оставлю их в качестве упражнения для читателя.

Теперь мы перейдем к различным исходным файлам Lua, которые включены в LuaSocket, такие как socket.lua и mime.lua. Вместо того, чтобы использовать require для их загрузки, мы собираемся выполнить их с помощью luaL_dofile.

Для того, чтобы быть конкретным, предположим, что мы хотим использовать LuaSocket для инициализации для нашего контроллера представлений. Мы создадим состояние Lua в viewDidLoad, вызовите luaL_openlibs, чтобы инициализировать основные библиотеки и библиотеки C LuaSocket, затем мы получим путь к файлам Lua, которые мы хотим запустить, с помощью подпрограмм от NSBundle.

Нам нужно отредактировать файлы Lua, чтобы удалить все строки, require socket.core, mime.core, и т.д., потому что это проще, чем пытаться получить require правильно вести себя. Кроме того, socket.core и mime.core уже были инициализированы нашим измененным luaL_openlibs, поэтому нет необходимости в require им.

Так viewDidLoad будет выглядеть примерно так:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    lua_State *L = luaL_newstate(); 
    luaL_openlibs(L); 

    // Load socket.lua and mime.lua 

    NSString *fp = [[NSBundle mainBundle] pathForResource:@"socket" ofType:@"lua"]; 
    luaL_dofile(L, [fp cStringUsingEncoding:NSUTF8StringEncoding]); 

    fp = [[NSBundle mainBundle] pathForResource:@"mime" ofType:@"lua"]; 
    luaL_dofile(L, [fp cStringUsingEncoding:NSUTF8StringEncoding]); 

    lua_settop(L, 0); // ignore return values from the calls to dofile 


    // Now do something with the Lua state and LuaSockets 

    NSString *script = @"res = mime.b64('LuaSocket', 'works')"; 
    luaL_dostring(L, [script cStringUsingEncoding:NSUTF8StringEncoding]); 
    lua_getglobal(L, "res"); 
    const char *s = luaL_checkstring(L, 1); 
    NSLog(@"res = %@", [NSString stringWithCString:s encoding:NSUTF8StringEncoding]); 
} 

Есть еще несколько свободных концов, но это должно продемонстрировать основные моменты. Вы можете посмотреть example project, который я создал на Github. В течение следующих нескольких дней я очищу его и продемонстрирую больше функциональности LuaSocket.

Смежные вопросы