Luapp 导出类虚函数的使用和对象传递

在上一篇《Luapp C++ 导出函数/类与Lua交互》介绍了如何导出类和函数。

这篇简单说说导出类虚函数的使用与对象传递

先看看基类和派生类的定义

 //基类,含有一个虚函数
 class TestClassBase {
 public:
	 virtual void print() const {
		 printf("base class print\n");
	 }
 };

 //派生类:导出
 class TestClass:public TestClassBase {
 public:
	 TestClass() {//从Lua创建  也可以在包含luaExportClass.h前重新定义宏 LUA_EXPORT_NEWOBJ,来自定义创建类对象,默认直接 new
		 m_createByLua = true;
		 printf("TestClass Constructor:Lua\n");
	 }

	 TestClass(int ) {//从c++创建
		 m_createByLua = false;
		 printf("TestClass Constructo:C++\n");
	 }

	 ~TestClass() {
		 if(m_createByLua)
			 printf("TestClass Destructor:Lua\n");
		 else
			 printf("TestClass Destructor:C++\n");
	 }

	 virtual void print() const override{
		 if(m_createByLua)
			printf("subclass:I am create by lua\n");
		 else
			printf("subclass:I am create by c++\n");
	 }

	 //该函数未导出
	 void printcpp() {
		 printf("not export function,only use in c++\n");
	 }

	 int add(int a, int b) {
		 return  a + b;
	 }

	 void setv(int value) {
		 m_value = value;
	 }

	 int getv() {
		 return m_value;
	 }

	 int m_value;
	 bool m_createByLua;
	 //导出申明
	 LUA_CLASS_EXPORT_DECLARE;
 };

导出实现宏,类似MFC消息映射

//不需要导出的成员函数,不写在这里即可 
LUA_CLASS_EXPORT_BEGIN(TestClass)  //导出实现开始
	 LUA_CLASS_EXPORT_FUNC("add", &TestClass::add) //设定导出的成员函数名和函数地址
	 LUA_CLASS_EXPORT_FUNC("getvalue", &TestClass::getv) //在lua里换个名字
	 LUA_CLASS_EXPORT_FUNC("setv", &TestClass::setv) 
	 LUA_CLASS_EXPORT_FUNC("ppt", &TestClassBase::print) //基类虚函数,调用派生类的函数
LUA_CLASS_EXPORT_END() //结束

这样就完成了派生类 TestClass 的导出。 

从lua获取所需的参数,返回值给lua,都是自动操作。

使用时不用关心lua栈。

1.Lua创建c++对象,并在lua使用

lua::LuaWrap lw;
lw.Init();//对象初始化

//调用导出类的  LuaClassRegister 函数导出该类到当前状态机
TestClass::LuaClassRegister(lw.get());

//对象在lua生成,并调用成员函数
lw.RunString<void>(
		 R"(
			 local t1 = TestClass() --new object:local
             local v = t1:add(1, 4)  -- 5
             t1:setv(6) 
             t2 = TestClass() --new object:global
			 t2:setv(v)
             print('t1:getvalue()='..t1:getvalue())  --6
             print('t2:getvalue()='..t2:getvalue()) --5 
             t1:ppt()  --print
		)"
		 );

运行结果:

 

2.将Lua创建的对象,传递到c++使用

上面演示了在lua里创建TestClass对象并调用成员函数和虚函数。

现在,我们将lua创建的c++对象传递出来给c++调用

//定义一个 lambda ,导出给lua,接收lua传递的参数
auto UseLuaObj = [](void *o) {
    //如果参数为lightuserdata(先由c++通过void*传过去,再被传出来),则直接转换为对象指针
    //所以void *根据具体情况使用
    //这里接收lua传递过来的 TestClass 对象
	auto pobj = *(TestClass **)o;
	pobj->printcpp(); //打印,该函数未导出,仅能在c++里调用
};
lw.RegFunction("UseLuaObj", UseLuaObj);//注册函数 UseLuaObj 给 lua
lw.RunString<void>("UseLuaObj(t2)");//在lua里调用导出函数,将全局对象t2传出来

运行结果这里仅一条print,待会儿一起给出。

3.将在c++里创建的对象,传递给Lua使用

很多时候,我们已经在c++代码里创建了对象,想直接传递给lua使用,应该怎么操作呢?

可以这样实现:

首先在lua里定义一个函数,用一个参数接收c++传递的对象,c++传递时,使用 mtable类型即可

如下:

//对象已经在c++中生成,传递给lua使用
//编写一个lua函数,将c++创建的对象,传递给lua使用(该类已被导出)
TestClass tc(1);
lw.RunString<void>(
		 R"(
			 function PassByParam(p)
				 p:ppt() --print
		     end
		)",//定义lua函数 PassByParam
		 "PassByParam",//调用lua函数 PassByParam
		 lua::mtable{&tc,"TestClass"});//将tc指针作为导出的TestClass传递给函数 PassByParam

也可以使用宏 LUA_EXPORT_METATABLE(TestClass) 获取到导出类的mtable名。

由c++创建,通过mtable方式传递给Lua使用的对象,由c++销毁,lua不参与其生命周期管理。

由Lua代码调用TestClass()创建的c++对象,由Lua创建也由Lua销毁(随userdata回收)。

最后整体运行结果如图:

 

小结:新提交的代码补充了mtable类型的使用,完善了c++创建的对象传递给lua使用的情况。

当前:

Lua创建c++对象,在Lua使用或传递给C++使用

C++创建对象,传递给Lua使用

都已经实现了,新的代码和测试代码已提交到github:GitHub - njzz/luapp: lua and cpp

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值