【发布时间】:2011-05-06 18:34:20
【问题描述】:
我正在尝试直接从 C/C++ 设置我的全局 LUA_PATH 变量,我在我的 iPhone 应用程序中使用 Lua,所以我的路径往往会在应用程序之间发生变化(每个 iPhone 应用程序在设备中都有一个单独的文件夹)。
我知道我可以通过使用“固定”路径重新编译 lua 来设置 LUA_PATH,但这远非理想。
(我试图这样做是为了能够使用我的.lua 脚本中的require。
有人可以帮我吗?
【问题讨论】:
我正在尝试直接从 C/C++ 设置我的全局 LUA_PATH 变量,我在我的 iPhone 应用程序中使用 Lua,所以我的路径往往会在应用程序之间发生变化(每个 iPhone 应用程序在设备中都有一个单独的文件夹)。
我知道我可以通过使用“固定”路径重新编译 lua 来设置 LUA_PATH,但这远非理想。
(我试图这样做是为了能够使用我的.lua 脚本中的require。
有人可以帮我吗?
【问题讨论】:
我想这是不可能的,因为正如您所说,出于安全原因,每个 iPhone 应用程序都存在于自己的沙箱中。
我认为使用setenv 只会为当前进程及其子进程设置环境变量。
顺便说一句:如果计划将您的应用程序提交到 AppStore,(据我所知)脚本语言/解释器受您签署的合同的约束。
【讨论】:
#include <stdlib.h>
...
setenv ( "LUA_PATH", (char *)my_path, 1 );
...或者类似的东西...
【讨论】:
你也可以在调用require之前在Lua中更改package.path。
【讨论】:
我对 iPhone 开发不太熟悉,但是你能在执行你的应用程序之前设置 LUA_PATH 环境变量吗?
例如,在 Linux 中,我可以编写一个脚本来执行您的二进制文件,如下所示:
export LUA_PATH="foo"
/path/to/executable
Windows 具有与批处理文件类似的功能。
如果你真的需要在代码中更改它,我不知道该怎么做,除了使用 luaL_loadbuffer 和 lua_pcall 来执行“package.path = blah”命令。
【讨论】:
env LUA_PATH="foo" /path/to/executable。
在 C++ 中:
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!
}
我没有测试或编译它。我用过:http://lua.org/pil 和 http://lua.org/manual/5.1
【讨论】:
ObjC:从另一个答案开始,这对我有用。需要附加“/?.lua”。
int setLuaPath(NSString* 路径) { lua_getglobal(L, "包"); lua_getfield(L, -1, "路径"); // 从堆栈顶部的表中获取字段“路径” (-1) NSString * cur_path = [NSString stringWithUTF8String:lua_tostring( L, -1 )]; // 从栈顶抓取路径字符串 cur_path = [cur_path stringByAppendingString:@";"]; // 在这里做你的路径魔法 cur_path = [cur_path stringByAppendingString:path]; cur_path = [cur_path stringByAppendingString:@"/?.lua"]; lua_pop(L, 1); // 删除我们刚刚在第 5 行压入的堆栈中的字符串 lua_pushstring(L, [cur_path UTF8String]); //推送新的 lua_setfield( L, -2, "路径" ); // 将表中的“路径”字段设置为-2,其值位于堆栈顶部 lua_pop(L, 1); // 从栈顶删除包表 返回0; // 全做完了! } ...在某处添加此代码,例如在 lua_open() 附近 // 将 Lua 的 Package.path 设置为可以找到 Lua 文件的位置 NSString *luaPath = [[NSBundle mainBundle] pathForResource:@"我的任何一个 lua 文件的名称" ofType:@"lua"]; setLuaPath([luaPath stringByDeletingLastPathComponent]); ...【讨论】:
您可以通过执行几个 lual_dostring 函数非常轻松地在 c++ 中设置 LUA_PATH 和 LUA_CPATH。
luaL_dostring(L, "package.path = package.path .. ';?.lua'");
luaL_dostring(L, "package.cpath = package.cpath .. ';?.dll'");
这两行在你有你的 lua_State(这里是 L)之后和你的 lual_loadfile() 和 lau_pcall() 函数调用之前调用将添加到当前设置的路径和 cpath。在这种情况下,我在两个指令中都添加了一条指令以查看本地执行。
我花了几个小时才找到这个解决方案。我希望它有所帮助。
【讨论】:
luaL_dostring 返回并出错。我收到的消息是attempt to index a nil value (global 'package')
luaL_openlibs(L)。如果正确加载了包 lib,则此解决方案有效