Skip to content
\n

I'm registering the module with:

\n
globals.set(\"vec2\", lua.create_proxy::<Vec2>()?)?;
\n

It seems like the mlua userdata is dealing with this differently from the C API so it fails to detect the userdata as the correct type.

","upvoteCount":1,"answerCount":1,"acceptedAnswer":{"@type":"Answer","text":"

Check my example, it works:

\n
struct Vec2(f32, f32);\n\nlet lua = Lua::new();\n\nlet push_vector = lua.create_function(|lua, (x, y): (f32, f32)| {\n    let vec = Vec2(x, y);\n    lua.create_any_userdata(vec)\n})?;\nlua.set_named_registry_value(\"push_vector\", push_vector)?;\n\nlet get_vector = lua.create_function(|_, mut ud: UserDataRefMut<Vec2>| {\n    let vec: *mut Vec2 = &mut *ud;\n    Ok(Value::LightUserData(LightUserData(vec as *mut c_void)))\n})?;\nlua.set_named_registry_value(\"get_vector\", get_vector)?;\n\nunsafe extern \"C\" fn lua_isvector(L: *mut lua_State, idx: c_int) -> c_int {\n    !lua_tovector(L, idx).is_null() as c_int\n}\n\nunsafe extern \"C\" fn lua_pushvector(L: *mut lua_State, x: f32, y: f32) {\n    ffi::lua_getfield(L, ffi::LUA_REGISTRYINDEX, c\"push_vector\".as_ptr());\n    ffi::lua_pushnumber(L, x as f64);\n    ffi::lua_pushnumber(L, y as f64);\n    ffi::lua_call(L, 2, 1);\n}\n\nunsafe extern \"C\" fn lua_tovector(L: *mut lua_State, idx: c_int) -> *mut Vec2 {\n    let idx = lua_absindex(L, idx);\n    ffi::lua_getfield(L, ffi::LUA_REGISTRYINDEX, c\"get_vector\".as_ptr());\n    ffi::lua_pushvalue(L, idx);\n    let vec = match ffi::lua_pcall(L, 1, 1, 0) {\n        ffi::LUA_OK => ffi::lua_touserdata(L, -1) as *mut Vec2,\n        _ => std::ptr::null_mut(),\n    };\n    ffi::lua_pop(L, 1);\n    vec\n}\n\nunsafe {\n    lua.exec_raw::<()>((), |state| {\n        lua_pushvector(state, 1.0, 2.0);\n        println!(\"is vector: {}\", lua_isvector(state, -1));\n        let vec2 = lua_tovector(state, -1);\n        if !vec2.is_null() {\n            println!(\"vector: ({}, {})\", (*vec2).0, (*vec2).1);\n        }\n    })?;\n}
","upvoteCount":0,"url":"https://github.com/mlua-rs/mlua/discussions/545#discussioncomment-12530475"}}}
Discussion options

You must be logged in to vote

Check my example, it works:

struct Vec2(f32, f32);

let lua = Lua::new();

let push_vector = lua.create_function(|lua, (x, y): (f32, f32)| {
    let vec = Vec2(x, y);
    lua.create_any_userdata(vec)
})?;
lua.set_named_registry_value("push_vector", push_vector)?;

let get_vector = lua.create_function(|_, mut ud: UserDataRefMut<Vec2>| {
    let vec: *mut Vec2 = &mut *ud;
    Ok(Value::LightUserData(LightUserData(vec as *mut c_void)))
})?;
lua.set_named_registry_value("get_vector", get_vector)?;

unsafe extern "C" fn lua_isvector(L: *mut lua_State, idx: c_int) -> c_int {
    !lua_tovector(L, idx).is_null() as c_int
}

unsafe extern "C" fn lua_pushvector(L: *mut lua_State, x: f32, y: f32) {

Replies: 1 comment 3 replies

Comment options

You must be logged in to vote
3 replies
@bobbens
Comment options

@khvzak
Comment options

Answer selected by bobbens
@bobbens
Comment options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Q&A
Labels
None yet
2 participants