Lua绑定C++类

3 篇文章 0 订阅
1 篇文章 0 订阅

原文:http://blog.csdn.net/chenee543216/article/details/12074771

以下是代码:

Animal.h文件

#pragma once
#ifndef __ANIMAL_H__
#define __ANIMAL_H__

class Animal
{
public:
	Animal( const char *name );
	void setAge( int age );
	int getAge();
	void sound();
	~Animal(void);

private:
	const char *name;
	int age;
};

#endif


Animal.cpp文件

#include "stdafx.h"
#include "Animal.h"

Animal::Animal( const char* name ):age(0)
{
	this->name = name;
}

Animal::~Animal(void)
{
	printf( "Animal destructor." );
}

void Animal::setAge( int age )
{
	this->age = age;
}

int Animal::getAge()
{
	return this->age;
}

void Animal::sound()
{
	printf("--Animal-- name: %s, age:%d\n", this->name, this->age ); 
}


LuaAimal.h

#pragma once

#ifndef __LUA_ANIMAL__
#define __LUA_ANIMAL__

class Animal;

class LuaAnimal
{
public:
	~LuaAnimal(void);
	static void Register( lua_State *l );
private:
	static const char *className;
	static const luaL_reg methods[];
	static const luaL_reg methods_f[];

	static int create( lua_State *l );
	static int gc_animal( lua_State *l );
	static Animal *getAnimal( lua_State *l );

	static int sound( lua_State *l );
	static int setAge(lua_State *l);
	static int getAge(lua_State *l);
};

#endif


LuaAnimal.cpp

#include "stdafx.h"
#include "LuaAnimal.h"
#include "Animal.h"
#include "Utlis.h"

const char *LuaAnimal::className = "Animal";
const luaL_reg LuaAnimal::methods[] = {
	{"sound", LuaAnimal::sound },
	{"setAge", LuaAnimal::setAge},
	{"getAge", LuaAnimal::getAge},
	{"__gc", LuaAnimal::gc_animal},
	{NULL,NULL}
};

const luaL_reg LuaAnimal::methods_f[] = {
	{ "create", LuaAnimal::create },
	{ NULL, NULL}
};

LuaAnimal::~LuaAnimal(void)
{
}

void LuaAnimal::Register( lua_State *l )
{
	//1. new method table for l to save functions
	lua_newtable(l);
	int methodTable = lua_gettop(l);

	//2.new metatable for L to save "__metatable", "__index",  "__gc", etc
	luaL_newmetatable(l, className );
	int metaTable = lua_gettop(l);

	//3.0 metatable["__metatable"] = methodtable;
	lua_pushliteral( l, "__metatable" );  //remove \0
	lua_pushvalue( l, methodTable );
	lua_settable( l, metaTable );

	//4.0 metatable["__index"] = methodtable
	lua_pushliteral( l, "__index" );
	lua_pushvalue( l, methodTable );
	lua_rawset( l, metaTable );  // the same as lua_settable(1,metatable)

	//5.0 metatable["__gc"] = gc_animal  //will be called when lua_close(l)
	lua_pushliteral( l, "__gc" ); 
	lua_pushcfunction( l, LuaAnimal::gc_animal );
	lua_rawset( l, metaTable );

	lua_pop(l,1);	//drop metatable

	/*6.0 for object
	name -- null set object funtion to methodtable( the table on top );
	eg: Animal a = Animal("xxx")
	a:func in this methodtable
	fill methodtable, is libname is not null,
	will create a table use the libname and push the table to stack*/
	luaL_openlib( l, NULL, methods, 0 ); 
	lua_pop(l,1);		//drop methodtable

	/*7.1 for class:
	name = className, so this set function to "method_f"
	eg: Animal a = Animal:create( "xx" );
		Animal:create() in this method_f tables
	*/
	luaL_openlib( l, className, methods_f, 0 );  //push table[className] to stack
	lua_pop(l,1); //drop table[className]

	/*7.2 for class:
	add global function "className", so we Animal() is a global function now
	eg: Animal a = Animal("xx")
		function Animal() in lua will call create in C++
	*/
	//lua_register(l, className, LuaAnimal::create );
}

int LuaAnimal::create( lua_State *l )
{
	const char*name = lua_tostring(l,-1);

	Animal *a = new Animal(name);
	void **p = (void**)lua_newuserdata( l, sizeof(void*));  
	*p = a;

	luaL_getmetatable( l, className );
	lua_setmetatable( l, -2 );

	return 1;
}

Animal* LuaAnimal::getAnimal( lua_State *l )
{
	luaL_checktype( l, 1, LUA_TUSERDATA ); //indicate what type to check
	void *ud = luaL_checkudata( l, 1, className );
	if( !ud )
		luaL_typerror( l, 1, className );

	return *(Animal**)ud;
}

int LuaAnimal::gc_animal( lua_State *l )
{
	Utlis::stackDump(l);

	Animal *a = (Animal*)(*(void**)lua_touserdata(l,-1));
	delete a;
	return 0;
}

int LuaAnimal::getAge( lua_State *l )
{
	Animal *a = getAnimal(l);
	lua_pushinteger(l, a->getAge());
	return 1;
}

int LuaAnimal::setAge( lua_State *l )
{
	Animal *a = getAnimal(l);
	int age = luaL_checkint(l,2);
	a->setAge( age );
	return 0;
}

int LuaAnimal::sound( lua_State *l )
{
	Animal *a = getAnimal(l);
	a->sound();
	return 0;
}


工具类Utils,使用查看lua堆栈情况

Utils.h

#pragma once
#ifndef __UTLIS_H__
#define __UTLIS_H__

class Utlis
{
public:
	Utlis(void);
	~Utlis(void);
	static void stackDump( lua_State *l );
};

#endif


Utils.cpp

#include "stdafx.h"
#include "Utlis.h"


Utlis::Utlis(void)
{
}


Utlis::~Utlis(void)
{
}

void Utlis::stackDump( lua_State *l )
{
	int i;
	int top = lua_gettop( l );
	printf("------start-----%d\n", top);

	for( i = 1; i <= top; i++ )
	{
		int t = lua_type( l, i );
		printf("type: %s value:", lua_typename(l,t));

		switch (t)
		{
		case LUA_TSTRING:
			printf("%s", lua_tostring(l,i));
			break;
		case LUA_TBOOLEAN:
			printf( lua_toboolean(l,i)? "true" : "false" );
			break;
		case LUA_TNUMBER:
			printf("%g", lua_tonumber(l,i));
			break;

		default:
			printf("%s", lua_typename(l,t));
			break;
		}
		printf("\n");
	}

	printf("------end----\n" );
}


lua测试代码

main.lua

print( "test lua access C++ class" )

local function main()
  --使用luaL_openlib( l, className, methods_f, 0 )注册,
  --Animal是个table, 调用create方法
  --local s = Animal.create("xx") --lua_gettop()=1 1:xx
  local s = Animal:create("xx") --lua_gettop()=2 1:table, 2:xx, 相比.create多了一个table,指Animal本身
  s:setAge(100)
  s:sound()

  --使用lua_register(l, className, LuaAnimal::create )注册
  --Animal是个函数,直接调用方法

   --local a = Animal("ww")  
   --a:setAge(20)
   --a:sound()
end

main()


最后是C++测试代码

main.cpp

// TestLua.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "Utlis.h"
#include "LuaAnimal.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
	lua_State *l = lua_open();
	luaL_openlibs(l);
	
	LuaAnimal::Register(l);
	Utlis::stackDump(l);

	if( luaL_dofile( l, "main.lua" )){  // load and call
		Utlis::stackDump(l);
	}
	Utlis::stackDump(l);

	system("pause");
	lua_close(l);

	return 0;
}


 

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值