ios - lua require 函数在 iOS 上找不到我需要的文件

标签 ios lua require

我是 lua 的新手,这可能很简单,但我想不通。我整晚都在搜索,在这里阅读了一些帖子,但并不是我要找的东西。我终于找到了一个我不满意的蹩脚解决方案,所以我来这里寻求帮助。

我正在尝试将 lua 嵌入到 c++ 中,这个程序将作为 iPhone 上应用程序的一部分运行,正如我们所知,每个 iPhone 应用程序都有一个资源包,lua 脚本随包一起分发。

// I printed out the bundle path:
bundle directory /var/mobile/Applications/C6CEF090-B99A-4B9B-ADAC-F0BEF46B6EA4/LuaThirdTry.app

假设我在同一个文件夹中有两个脚本文件(main.lua、mylib.lua),我把它们放在我的 Xcode 项目中,组织如下:

somefolder
|--main.lua
|--mylib.lua

main.lua如下:

--main.lua
print(package.path)
require("mylib")

显然我想使用 mylib.lua 中的代码,但是,我从 lua vm 中得到了错误:

/usr/local/share/lua/5.2/?.lua;/usr/local/share/lua/5.2/?/init.lua;/usr/local/lib/lua/5.2/?.lua;/usr/local/lib/lua/5.2/?/init.lua;./?.lua
PANIC: unprotected error in call to Lua API (...090-B99A-4B9B-ADAC-F0BEF46B6EA4/LuaThirdTry.app/test.lua:5: module 'mylib' not found:
    no field package.preload['mylib']
    no file '/usr/local/share/lua/5.2/mylib.lua'
    no file '/usr/local/share/lua/5.2/mylib/init.lua'
    no file '/usr/local/lib/lua/5.2/mylib.lua'
    no file '/usr/local/lib/lua/5.2/mylib/init.lua'
    no file './mylib.lua'
    no file '/usr/local/lib/lua/5.2/mylib.so'
    no file '/usr/local/lib/lua/5.2/loadall.so'
    no file './mylib.so')

当我添加一行修改 package.path 时,我让它正确运行:

--main.lua modified
print(package.path)
package.path = package.path .. ";/var/mobile/Applications/C6CEF090-B99A-4B9B-ADAC-F0BEF46B6EA4/LuaThirdTry.app/?.lua"
require("mylib")

但这是绝对路径,绝对应该避免。 解决这个问题的一种方法是为lua提供一个来自c的函数,该函数在运行时将ipa bundle中的lua文件的完整路径返回给lua脚本,并将package.path与该路径连接起来,但我认为不应该这样这样做的“官方”方式。

我注意到 package.path 变量中有“./?.lua”,我只是想知道为什么找不到 mylib.lua,难道不是同一目录下的文件吗?

抱歉废话,所以问题是:我如何在 iOS 环境中正确地执行“要求”?

最佳答案

好的,我终于找到了一个好的答案,工作完成了,感谢this answer .

所以,解决办法就是修改c++代码中的路径,添加这个函数

#include <string>

int setLuaPath(lua_State* L, const char* path) {
    lua_getglobal(L, "package");
    lua_getfield(L, -1, "path"); // get field "path" from table at top of stack (-1)
    std::string cur_path = lua_tostring(L, -1); // grab path string from top of stack
    cur_path.append(";"); // do your path magic here
    cur_path.append(path);
    lua_pop(L, 1); // get rid of the string on the stack we just pushed on line 5
    lua_pushstring(L, cur_path.c_str()); // push the new one
    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
    return 0; // all done!
}

然后,在初始化lua_State时调用这个函数:

// yourfile.cpp
void runLua() {
    lua_State *L;
    L = luaL_newstate();
    luaL_openlibs(L);

    OCCaller oc_caller;
    std::string bundlePath = oc_caller.get_ios_bundle_path();
    bundlePath.append("/?.lua");
    setLuaPath(L, bundlePath.c_str());

    ....
}

您的 oc_caller 类可能如下所示:

// OCCaller.h
#ifndef __LuaThirdTry__OCCaller__
#define __LuaThirdTry__OCCaller__

#include <iostream>

class OCCaller {
public:
    OCCaller();
    ~OCCaller();
    std::string get_ios_bundle_path();

};

#endif

实现文件:

// OCCaller.mm
#include "OCCaller.h"
#import <Foundation/Foundation.h>

OCCaller::OCCaller() { }
OCCaller::~OCCaller() { }

std::string OCCaller::get_ios_bundle_path() {
    NSString *bundlePath = [[NSBundle mainBundle]resourcePath];
    return std::string([bundlePath UTF8String]);
}

关于ios - lua require 函数在 iOS 上找不到我需要的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22492741/

相关文章:

ios - 根据 Int 查找 JSON 字典中的前 10 项

ios - NSSet:我应该在 NSSet 中使用 float/double 吗?

image - 在 Torch (lua) 中可视化中间层中的图像

javascript - nodejs导入需要转换

ios - iOS 中两种纹理的非幂

从 C : errors 调用 Lua 脚本

dictionary - ngx.shared.DICT 使用安全吗?

node.js - 在 node.js 中 require 如何与 new 运算符一起工作?

javascript - 谷歌云功能::无法使用 'require'语句

ios - ITC.apps.assetvalidation.BITCODE_IMBALANCE_ERROR.error.message