gpt4 book ai didi

c++ - lua C API : class accessors

转载 作者:行者123 更新时间:2023-11-30 03:40:55 25 4
gpt4 key购买 nike

我已经实现了一个 lua 包装器,以在这篇文章之后使用 lua 中的用户数据访问 C++ 类:http://lua-users.org/wiki/BindingWithMembersAndMethods

我的 C++ 类如下所示:

class GameObject
{
public:
GameObject();
~GameObject();

int m_id;
float m_scale;
const char* m_path;
};

到目前为止,我可以在 lua 中执行此操作:

gameObject = GameObject.new()
gameObject.path = "test"
gameObject.scale = 2
local path = gameObject.path
local scale = gameObject.scale
print(scale)
print(path)

除了打印路径变量外,一切正常:

console output

“set string”行来 self 放入 setter 函数的调试:

int LuaGameObjectManager::set_string (lua_State *L, void *v)
{
v = (void*)luaL_checkstring(L, 3);
std::cout << "set string : " << (char*) v << std::endl;
return 0;
}

所以我想我正在设置正确的值,并且在使用此 getter 函数获取它时一定会出现问题:

int LuaGameObjectManager::get_string (lua_State *L, void *v)
{
char * tmp = (char*)v;
lua_pushstring(L, tmp );
return 1;
}

这就是我定义方法和元表的方式:

static const luaL_Reg methodsArray[] = {
{"new", New},
{"load", load},
{0,0}
};

static const luaL_Reg metaArray[] = {
{"__gc", gc},
{"__tostring", toString},
{0, 0}
};

static LuaManager::Xet_reg_pre gettersArray[] = {
{"scale", get_int, offsetof(GameObject, m_scale) },
{"path", get_string, offsetof(GameObject, m_path) },
{0,0}
};

static LuaManager::Xet_reg_pre settersArray[] = {
{"scale", set_int, offsetof(GameObject, m_scale) },
{"path", set_string, offsetof(GameObject, m_path) },
{0,0}
};

那么有人知道我为什么要打印一些奇怪的值吗?这是编码问题吗?我知道你们需要更多代码来理解我的问题并帮助我,但是注册 lua 方法和元表的整个部分很长,所以请告诉我您希望我发布什么代码。

最佳答案

我可以看到两个问题。

  1. 在函数内部分配给(原始)局部变量对外部世界没有影响。

    int LuaGameObjectManager::set_string (lua_State *L, void *v)
    {
    v = (void*)luaL_checkstring(L, 3);

    v 在这里是一个局部变量,所以这不会改变 set_string 方法之外的任何内容。您的对象的内存布局如下所示:

                  v
    \
    | int | float |pointer|
    \
    |c|c|c|c|c|...

    所以,你可能想要类似的东西

    *((char**)v) = luaL_checkstring(L, 3);

    但是请注意 luaL_checkstring 返回的字符串是由 Lua 管理的并且可以在任何时候被垃圾回收,所以你应该复制它(并且你必须清理之前的m_path 的值,否则会发生内存泄漏)。我会把细节留给你......

  2. 您发布的 get_string 方法(在您链接的 wiki 文章中使用了该方法)假定它正在处理内联字符数组。

                  v
    \
    | int | float |c|c|c|c|c|...

    您的情况有所不同,因为您使用的是指向字符数组第一个元素的指针(见上文)。一个正确的实现应该是这样的:

    int LuaGameObjectManager::get_string (lua_State *L, void *v)
    {
    lua_pushstring(L, *((char**)v));
    return 1;
    }

    在这种情况下,lua_pushstring 已经为您制作了一份拷贝(最终将由 Lua 进行垃圾回收),因此您不必考虑这一点。

关于c++ - lua C API : class accessors,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37681827/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com