在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称(OpenSource Name):tomaka/hlua开源软件地址(OpenSource Url):https://github.com/tomaka/hlua开源编程语言(OpenSource Language):C 72.2%开源软件介绍(OpenSource Introduction):hluaThis library is a high-level binding for Lua 5.2. You don't have access to the Lua stack, all you can do is read/write variables (including callbacks) and execute Lua code. How to install it?Add this to the [dependencies]
hlua = "0.3" How to use it?extern crate hlua;
use hlua::Lua; The let mut lua = Lua::new(); // mutable is mandatory You can check the documentation here. Reading and writing variableslua.set("x", 2);
lua.execute::<()>("x = x + 1").unwrap();
let x: i32 = lua.get("x").unwrap(); // x is equal to 3 Reading and writing global variables of the Lua context can be done with The base types that can be read and written are: If you wish so, you can also add other types by implementing the Executing Lualet x: u32 = lua.execute("return 6 * 2;").unwrap(); // equals 12 The You can also call lua.execute_from_reader::<()>(File::open(&Path::new("script.lua")).unwrap()) Writing functionsIn order to write a function, you must wrap it around fn add(a: i32, b: i32) -> i32 {
a + b
}
lua.set("add", hlua::function2(add));
lua.execute::<()>("local c = add(2, 4)"); // calls the `add` function above
let c: i32 = lua.get("c").unwrap(); // returns 6 In Lua, functions are exactly like regular variables. You can write regular functions as well as closures: lua.set("mul", hlua::function2(|a: i32, b: i32| a * b)); Note that the lifetime of the Lua context must be equal to or shorter than the lifetime of closures. This is enforced at compile-time. let mut a = 5i;
{
let mut lua = Lua::new();
lua.set("inc", || a += 1); // borrows 'a'
for i in (0 .. 15) {
lua.execute::<()>("inc()").unwrap();
}
} // unborrows `a`
assert_eq!(a, 20) Error handlingIf your Rust function returns a Manipulating Lua tablesManipulating a Lua table can be done by reading a let mut table: hlua::LuaTable<_> = lua.get("a").unwrap(); You can then iterate through the table with the for (key, value) in table.iter().filter_map(|e| e) {
...
} You can also retreive and modify individual indices: let x = table.get("a").unwrap();
table.set("b", "hello"); Calling Lua functionsYou can call Lua functions by reading a lua.execute::<()>("
function get_five()
return 5
end");
let get_five: hlua::LuaFunction<_> = lua.get("get_five").unwrap();
let value: i32 = get_five.call().unwrap();
assert_eq!(value, 5); This object holds a mutable reference of Reading and writing Rust containers(note: not yet possible to read all containers, see below) It is possible to read and write whole Rust containers at once: lua.set("a", [ 12, 13, 14, 15 ]);
let hashmap: HashMap<i32, f64> = [1., 2., 3.].into_iter().enumerate().map(|(k, v)| (k as i32, *v as f64)).collect();
lua.set("v", hashmap); If the container has single elements, then the indices will be numerical. For example in the code above, the If the container has tuples of two elements, then the first one will be considered as the key and the second one as the value. This can be useful to create APIs: fn foo() { }
fn bar() { }
lua.set("mylib", [
("foo", hlua::function0(foo)),
("bar", hlua::function0(bar))
]);
lua.execute::<()>("mylib.foo()"); It is possible to read a let mut lua = Lua::new();
lua.execute::<()>(r#"v = { 1, 2, 3 }"#).unwrap();
let read: Vec<_> = lua.get("v").unwrap();
assert_eq!(
read,
[1., 2., 3.].iter()
.map(|x| AnyLuaValue::LuaNumber(*x)).collect::<Vec<_>>()); In case table represents sparse array, has non-numeric keys, or
indices not starting at 1, It is possible to read a let mut lua = Lua::new();
lua.execute::<()>(r#"v = { [-1] = -1, ["foo"] = 2, [2.] = 42 }"#).unwrap();
let read: HashMap<_, _> = lua.get("v").unwrap();
assert_eq!(read[&AnyHashableLuaValue::LuaNumber(-1)], AnyLuaValue::LuaNumber(-1.));
assert_eq!(read[&AnyHashableLuaValue::LuaString("foo".to_owned())], AnyLuaValue::LuaNumber(2.));
assert_eq!(read[&AnyHashableLuaValue::LuaNumber(2)], AnyLuaValue::LuaNumber(42.));
assert_eq!(read.len(), 3); User data(note: the API here is very unstable for the moment) When you expose functions to Lua, you may wish to read or write more elaborate objects. This is called a user data. To do so, you should implement the struct Foo;
impl<L> hlua::Push<L> for Foo where L: hlua::AsMutLua<'lua> {
fn push_to_lua(self, lua: L) -> hlua::PushGuard<L> {
lua::userdata::push_userdata(self, lua,
|mut metatable| {
// you can define all the member functions of Foo here
// see the official Lua documentation for metatables
metatable.set("__call", hlua::function0(|| println!("hello from foo")))
})
}
}
fn main() {
let mut lua = lua::Lua::new();
lua.set("foo", Foo);
lua.execute::<()>("foo()"); // prints "hello from foo"
} Creating a Lua moduleNote: OBSOLETE ; this is still some pre-Rust-1.0 stuff This library also includes a second library named To use it, add this to [dependencies.rust-hl-lua-modules]
git = "https://github.com/tomaka/hlua" Then you can use it like this: #![feature(phase)]
#[!plugin(rust-hl-lua-modules)]
#[export_lua_module]
pub mod mylib { // <-- must be the name of the Lua module
static PI: f32 = 3.141592;
fn function1(a: int, b: int) -> int {
a + b
}
fn function2(a: int) -> int {
a + 5
}
#[lua_module_init]
fn init() {
println!("module initialized!")
}
} This module will then be usable by Lua: > mylib = require("mylib")
module initialized!
> return mylib.function1(2, 4)
6
> return mylib.PI
3.141592 Two syntax extensions are defined:
Restrictions:
ContributingContributions are welcome! |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论