lua调用C++类

1 篇文章 0 订阅

参考博客:

http://xxnull.blog.163.com/blog/#m=0&t=1&c=fks_084064083087082067086082086095085081087064093094087070083

http://www.tairan.com/archives/5493

http://blog.codingnow.com/2007/05/lua_winproc.html

http://www.cnblogs.com/ringofthec/archive/2010/11/09/lua_State.html

lua手册(主要是用来查询api):

http://manual.luaer.cn/

http://www.lua.org/manual/5.2/manual.html

最近学习如何将C++的类导出为一个.so并提供给lua调用,以此记录,以备日后查阅。本文的代码大多取自第二篇参考博客,至于如何在lua中调用C/C++代码中的函数在第一篇参考博客中有详细的教程,在此也感谢这两篇博客,它们解答了我关于lua虚拟机调用机制的很多疑惑。

参考博客1中讲解得比较详细,将C++类绑定到lua,其实就是绑定C++类的方法,并绑定一个构造方法,用以创建这个类对象。一个类对象在lua中表现为一个table,为了像C++一样访问类方法,我们将c++类的方法注册到table的元表里,具体注册的方法可以参考本文开头的两篇博客,这里不详述。

//CTest.cpp
#include <stdio.h>
#include <lua.hpp>

class CTest
{
public:
    CTest(){};
    virtual ~CTest(){};
    int Add(int x, int y)
    {
        printf("%p Add: x=%d, y=%d\n", this, x, y);
        return x + y;
    }
};

static int CreateCTest(lua_State *L)
{
    *(CTest**)lua_newuserdata(L, sizeof(CTest*)) = new CTest();
    luaL_getmetatable(L, "CTest");
    lua_setmetatable(L, -2);
    return 1;
}

static int DestoryCTest(lua_State *L)
{
    delete *(CTest**)lua_topointer(L, 1);
    return 0;
}

static int CallAdd(lua_State *L)
{
    CTest *pT = *(CTest**)lua_topointer(L, 1);
    lua_pushnumber(L, pT->Add(lua_tonumber(L, 2), lua_tonumber(L, 3)));
    return 1;
}

extern "C" int luaopen_LuaUseClass(lua_State *L)
{
    //lua_State *L = luaL_newstate();

    lua_pushcfunction(L, CreateCTest);
    lua_setglobal(L, "CTest");

    luaL_newmetatable(L, "CTest");
    lua_pushstring(L, "__gc");
    lua_pushcfunction(L, DestoryCTest);
    lua_settable(L, -3);
    lua_pushstring(L, "__index");
    lua_pushvalue(L, -2);
    lua_settable(L, -3);

    lua_pushstring(L, "Add");
    lua_pushcfunction(L, CallAdd);
    lua_settable(L, -3);
    lua_pop(L, 1);
    

    return 1;
}

int main(int argc, char *argv[])
{
    lua_State *L = luaL_newstate();
    luaopen_base(L);

    lua_pushcfunction(L, CreateCTest);
    lua_setglobal(L, "CTest");

    luaL_newmetatable(L, "CTest");
    lua_pushstring(L, "__gc");
    lua_pushcfunction(L, DestoryCTest);
    lua_settable(L, -3);
    lua_pushstring(L, "__index");
    lua_pushvalue(L, -2);
    lua_settable(L, -3);

    lua_pushstring(L, "Add");
    lua_pushcfunction(L, CallAdd);
    lua_settable(L, -3);
    lua_pop(L, 1);
    
    luaL_dofile(L, "LuaUseClassLua.lua");
    lua_close(L);

    return 0;
}

--LuaUseClassLua.lua
c = CTest()
print("c.Add(1, 2)==>" .. c:Add(1, 2))
d = CTest()
print("d.Add(4, 5)==>" .. d:Add(4, 5))

#Makefile
CC=g++

LuaUseClass : LuaUseClass.cpp
	$(CC) -o LuaUseClass LuaUseClass.cpp -llua -ldl
LuaUseClass.so : LuaUseClass.cpp
	$(CC) -o LuaUseClass.so LuaUseClass.cpp -fPIC -shared
clean :
	rm LuaUseClass

--test.lua
require "LuaUseClass"
c = CTest()
print("c.Add(1, 2)==>" .. c:Add(1, 2))
d = CTest()
print("d.Add(4, 5)==>" .. d:Add(4, 5))

上面用make LuaUseClass.so可以生成一个so文件,并可有test.lua调用,也可以用makeLuaUseClass生成一个可执行文件,该文件在c++代码中导出函数接口到lua,并在c++代码中执行LuaUseClassLua.lua脚本

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值