lua5.1.4下绑定c++类

Student.h文件

#ifndef __STUDENT_H__
#define __STUDENT_H__

#include 
#include 

const int SEX_MALE      = 0;
const int SEX_FEALE     = 1;
const int SEX_UNKNOWN   = 3;

class Student
{
public:
    Student();
    Student(std::string strName, int nAge, int nSex);
    ~Student();

    void SetName(std::string strName);
    std::string GetName();

    void SetAge(int nAge);
    int GetAge();

    void SetSex(int nSex);
    int GetSex();

private:
    std::string m_strName;
    int m_nAge;
    int m_nSex;
};

#endif // !__STUDENT_H__

Student.cpp文件

#include "Student.h"

Student::Student()
{
    std::cout << "create a student" << std::endl;

    m_strName = "unknown";
    m_nAge = 0;
    m_nSex = SEX_UNKNOWN;
}

Student::Student(std::string strName, int nAge, int nSex)
{
    std::cout << "create a student" << std::endl;

    m_strName = strName;
    m_nAge = nAge;
    m_nSex = nSex;
}

Student::~Student()
{
    std::cout << "kill a student" << std::endl;
}

void Student::SetName(std::string strName)
{
    m_strName = strName;
}

void Student::SetAge(int nAge)
{
    m_nAge = nAge;
}

void Student::SetSex(int nSex)
{
    m_nSex = nSex;
}

std::string Student::GetName()
{
    return m_strName;
}

int Student::GetAge()
{
    return m_nAge;
}

int Student::GetSex()
{
    return m_nSex;
}

BindCpp.h文件

#ifndef __BIND_CPP_H__
#define __BIND_CPP_H__

#include 
#include "Student.h"

extern "C"
{
#include 
#include 
#include 
}

typedef int LUA_CPP_API;

const int ERROR_PARAMS_VALUE    = 1;
const int ERROR_PARAMS_COUNTS   = 2;

const char* strPackageName = "myStudent";

LUA_CPP_API LuaCreateStudent(lua_State *L);
LUA_CPP_API LuaSetName(lua_State *L);
LUA_CPP_API LuaGetName(lua_State *L);
LUA_CPP_API LuaSetAge(lua_State *L);
LUA_CPP_API LuaGetAge(lua_State *L);
LUA_CPP_API LuaSetSex(lua_State *L);
LUA_CPP_API LuaGetSex(lua_State *L);
LUA_CPP_API LuaAutoGC(lua_State *L);

static const luaL_Reg luaRegStudenCtorFunc[] = {
    { "create", LuaCreateStudent },
    { NULL, NULL }
};

static const luaL_Reg luaRegStudentMenberFuncs[] = {
    { "setName", LuaSetName },
    { "getName", LuaGetName },
    { "setAge", LuaSetAge },
    { "getAge", LuaGetAge },
    { "setSex", LuaSetAge },
    { "getSex", LuaGetSex },
    { "__gc", LuaAutoGC },
    { NULL, NULL }
};


extern "C" int __declspec(dllexport) luaopen_Student(lua_State *L)
{
    if (L)
    {
        lua_newtable(L);
        int methodtable = lua_gettop(L);

        luaL_newmetatable(L, strPackageName);
        int metatable = lua_gettop(L);

        lua_pushliteral(L, "__metatable");
        lua_pushvalue(L, methodtable);
        lua_settable(L, metatable);

        lua_pushliteral(L, "__index");
        lua_pushvalue(L, methodtable);
        lua_settable(L, metatable);

        lua_pushliteral(L, "__gc");
        lua_pushcfunction(L, LuaAutoGC);
        lua_settable(L, metatable);

        lua_pop(L, 1);


        luaL_openlib(L, 0, luaRegStudentMenberFuncs, 0);
        lua_pop(L, 1);                 

        luaL_openlib(L, strPackageName, luaRegStudenCtorFunc, 0);
    }

    return 1;
}

#endif // !__BIND_CPP_H__

BindCpp.cpp文件

#include "BindCpp.h"


LUA_CPP_API LuaCreateStudent(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)lua_newuserdata(L, sizeof(Student*));
        if (pStudent)
        {
            *pStudent = new Student();
            luaL_getmetatable(L, strPackageName);
            lua_setmetatable(L, -2);

            return 1;
        }
    }

    return 0;
}

LUA_CPP_API LuaSetName(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent && lua_isstring(L, -1))
        {
            std::string strName = lua_tostring(L, -1);
            (*pStudent)->SetName(strName);
        }
    }

    return 0;
}

LUA_CPP_API LuaGetName(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent)
        {
            std::string strName = (*pStudent)->GetName();
            lua_pushstring(L, strName.c_str());
        }
    }

    return 1;
}

LUA_CPP_API LuaSetAge(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent && lua_isnumber(L, -1))
        {
            int nAge = int(lua_tointeger(L, -1));
            (*pStudent)->SetAge(nAge);
        }
    }

    return 0;
}

LUA_CPP_API LuaGetAge(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent)
        {
            int nAge = (*pStudent)->GetAge();
            lua_pushinteger(L, nAge);
        }
    }

    return 1;
}

LUA_CPP_API LuaSetSex(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent && lua_isnumber(L, -1))
        {
            int nSex = int(lua_tointeger(L, -1));
            (*pStudent)->SetSex(nSex);
        }
    }

    return 0;
}

LUA_CPP_API LuaGetSex(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent)
        {
            int nSex = (*pStudent)->GetSex();
            lua_pushinteger(L, nSex);
        }
    }

    return 1;
}

LUA_CPP_API LuaAutoGC(lua_State *L)
{
    if (L)
    {
        Student** pStudent = (Student**)luaL_checkudata(L, 1, strPackageName);
        if (pStudent)
        {
            delete *pStudent;
        }
    }

    return 0;
}

将以上代码编译为dll动态库即可

main.lua文件

local Student = require("Student")

if Student then
    local student = Student.create()
    local name = student:getName()
    local age = student:getAge()
    local sex = student:getSex()
    print(name, age, sex)
end

你可能感兴趣的:(lua5.1.4下绑定c++类)