草庐IT

c++ - 注册用于 Lua 5.2 的 C++ 类

coder 2024-02-10 原文

所以我正在阅读如何通过 THIS little blog tutorial 为 Lua 创建和注册一个 C++ 类.

但尽管它简单、信息丰富且清晰易读,但它似乎适用于旧版本的 Lua。

所以一些函数/宏要么丢失了,要么只是具有不同的签名。

以下代码在 Lua C 5.2 版中会是什么样子?

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#include <stringstream>
#include <string>

using namespace std;

// Just a useless test class
class MyClass
{
private:
    int _X;

public:
    MyClass(int x) : _X(x) {};
    ~MyClass() { Release() };

    // Displays your number in a welcoming message box
    void Hello()
    {
        stringstream ss;
        ss << "Hello!" << endl << "Your number is: " << _X;
        string s(ss.str());
        MessageBoxA(NULL, s.c_str(), "MyClass", MB_ICONINFORMATION);
    }

    void Release() {
        //release code goes here
    }
};

// Functions that will create/destroy MyClass instances
static int newMyClass(lua_State* L)
{
    int n = lua_gettop(L); // Number of arguments
    if (n != 2)
        return luaL_error(L, "Got %d arguments, expected 2 (class, x)", n);
    // First argument is now a table that represent the class to instantiate
    luaL_checktype(L, 1, LUA_TTABLE);

    lua_newtable(L); // Create table to represent instance

    // Set first argument of new to metatable of instance
    lua_pushvalue(L, 1);
    lua_setmetatable(L, -2);

    // Do function lookups in metatable
    lua_pushvalue(L, 1);
    lua_setfield(L, 1, "__index");

    // Allocate memory for a pointer to to object
    MyClass** s = (MyClass**)lua_newuserdata(L, sizeof(MyClass*));

    int x = luaL_checknumber(L, 2);

    *s = new MyClass(x);

    luaL_getmetatable(L, "Lua.MyClass");
    lua_setmetatable(L, -2);
    lua_setfield(L, -2, "__self");

    return 1;
}

static int doSomethingMyClass(lua_State* L)
{
    MyClass* c = nullptr;
    checkUserData(L, "Lua.MyClass", c);
    c->Hello();
    return 0;
}

static int destroyMyClass(lua_State* L)
{
    MyClass* c = nullptr;
    checkUserData(L, "Lua.MyClass", c);
    c->Release();
    return 0;
}

// Functions that will show up in our Lua environment
static const luaL_Reg gMyClassFuncs[] = {
    // Creation
    { "new", newMyClass) },
    { "hello", helloMyClass },
    { NULL, NULL }
};

static const luaL_Reg gDestroyMyClassFuncs[] = {
    {"__gc", destroyMyClass},
    {NULL, NULL}
};

// Registers the class for use in Lua
void registerMyClass(lua_State *L)
{  
    // Register metatable for user data in registry
    luaL_newmetatable(L, "Lua.MyClass");
    luaL_register(L, 0, gDestroyMyClassFuncs);      
    luaL_register(L, 0, gMyClassFuncs);      
    lua_pushvalue(L, -1);
    lua_setfield(L, -2, "__index");  

    // Register the base class for instances of Sprite
    luaL_register(L, "MyClass", gSpriteFuncs);  
}


基本上,这里的目标是能够在 Lua 中编写以下内容:

-- Create a new MyClass instance
local c = MyClass:new(5)
-- Show message
c:Hello() -- Should say something like "Hello! Your number is: 5"

我需要更改什么才能使其适用于 5.2?

最佳答案

该代码中唯一不属于 Lua 5.2 的函数是 luaL_register。您应该改用 luaL_setfuncs

您还应该手动设置全局 MyClass 或在您的 Lua 代码中使用 local MyClass=require"MyClass" 因为 require 不再设置全局变量。

如果您正在嵌入 Lua,您可以使用 -DLUA_COMPAT_MODULE 编译它和您的代码并获得 5.1 函数。但是考虑一下,如果您打算使用这个版本,现在是将您的代码移至 Lua 5.2 的好时机。

关于c++ - 注册用于 Lua 5.2 的 C++ 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16879660/

有关c++ - 注册用于 Lua 5.2 的 C++ 类的更多相关文章

  1. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  2. ruby - 难道Lua没有和Ruby的method_missing相媲美的东西吗? - 2

    我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  5. ruby - inverse_of 是否适用于 has_many? - 2

    当我使用has_one时,它​​工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290

  6. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

  7. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  8. 阿里云国际版免费试用:如何注册以及注意事项 - 2

    作为新的阿里云用户,您可以50免费试用多种优惠,价值高达1,700美元(或8,500美元)。这将让您了解和体验阿里云平台上提供的一系列产品和服务。如果您以个人身份注册免费试用,您将获得价值1,700美元的优惠。但是,如果您是注册公司,您可以选择企业免费试用,提交基本信息通过企业实名注册验证,即可开始价值$8,500的免费试用!本教程介绍了如何设置您的帐户并使用您的免费试用版。​关于免费试用在我们开始此试用之前,您还必须遵守以下条款和条件才能访问您的免费试用:只有在一年内创建的账户才有资格获得阿里云免费试用。通过此免费试用优惠,用户可以免费试用免费试用活动页面上列出的每种产品一次。如果您有多个帐

  9. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  10. ruby-on-rails - 设计注册确认 - 2

    我在我的项目中有一个用户和一个管理员角色。我使用Devise创建了身份验证。在我的管理员角色中,我没有任何确认。在我的用户模型中,我有以下内容:devise:database_authenticatable,:confirmable,:recoverable,:rememberable,:trackable,:validatable,:timeoutable,:registerable#Setupaccessible(orprotected)attributesforyourmodelattr_accessible:email,:username,:prename,:surname,:

随机推荐