2015-02-07 105 views
1

我正在開發一個iOS應用程序,可以運行Lua腳本,我可以很容易地將基地lua支持與CocoaPods集成,但我怎樣才能將LuaSocket庫添加進去呢? LuaSocket包含一些C和一些Lua文件,有沒有人有想法?謝謝!如何在iOS應用程序中使用LuaSocket?

回答

1

我使用了LuaSocket的2.0.2版本和Lua的5.1版本。修改了一些文件後[未知類型名'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

與iOS 8允許動態框架(庫)有馬y是一個更優雅的方法,但以下方法適用於Lua 5.2.3(,因爲您使用Cocoapods,而5.2.3是Cocoapod提供的版本)和LuaSocket 3.0-rc1

請注意,我實際上沒有使用Cocoapod;包括你的iOS項目中的Lua很簡單,我覺得使用Cocoapods不值得。因人而異。由於路徑差異,您可能需要對以下描述的內容進行一些調整。

  1. 創建一個新的iOS '單一視圖' 項目
  2. 中創建一個Xcode的項目導航
  3. 複製命名的Lua組從所有文件(除了lua.c,luac.c,lua.hpp和Makefile)在src目錄中的Lua下載到該組
  4. 中創建一個Xcode的項目導航
  5. 複製命名LuaSocket組從LuaSockets的src目錄下的所有文件(除了makefile文件,wsocket.c,wsocket.h)下載到這個組
  6. #import "luasocket.h"添加到該文件serial.h在LuaSocket源

此時,你應該能夠沒有任何錯誤,構建和運行應用程序。當然,它還沒有做任何事情......

首先,我們要修改luaL_openlibs,以便它初始化LuaSocket的C代碼,如下所示。

在Lua源代碼中找到文件linit。c和改變

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} 
}; 

你需要在linit.c的頂部添加#include "luasocket.h"#include "mime.h"

還有一些其他C函數需要添加到此列表中,例如luaopen_socket_unix,但我會將它們作爲練習插入讀者。

現在我們將轉向LuaSocket中包含的各種Lua源文件,例如socket.lua和mime.lua。我們將使用luaL_dofile來執行它們,而不是使用require加載它們。

爲了具體,假設我們想要使用LuaSocket爲我們的視圖控制器做一些初始化。我們將在viewDidLoad中創建Lua狀態,調用luaL_openlibs,初始化核心庫和LuaSocket的C庫,然後我們將使用NSBundle的例程獲取我們想要運行的Lua文件的文件路徑。

我們需要編輯的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]); 
} 

還有一些枝節問題,但這應該表現出的要點。你可以看看我在Github上創建的example project。在接下來的幾天裏,我會清理它並演示更多LuaSocket的功能。

相關問題