主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍)

部分内容查阅自:《Lua 5.3  参考手册》中文版 译者 云风 制作 Kavcc

vs2013+lua-5.3.3

1.C++中学生Student类

①头文件Student.h

 #pragma once

 #include <iostream>
#include <string> class Student
{
public:
//构造/析构函数
Student();
~Student(); //get/set函数
std::string get_name();
void set_name(std::string name);
unsigned get_age();
void set_age(unsigned age); //打印函数
void print(); private:
std::string _name;
unsigned _age;
};

②实现文件student.cpp

 #include "Student.h"

 Student::Student()
:_name("Empty"),
_age()
{
std::cout << "Student Constructor" << std::endl;
} Student::~Student()
{
std::cout << "Student Destructor" << std::endl;
} std::string Student::get_name()
{
return _name;
} void Student::set_name(std::string name)
{
_name = name;
} unsigned Student::get_age()
{
return _age;
} void Student::set_age(unsigned age)
{
_age = age;
} void Student::print()
{
std::cout << "name :" << _name << " age : " << _age << std::endl;
}

2.C++中定义注册全局函数到Lua中

①头文件StudentRegFuncs.h

 #pragma once

 #include "Student.h"
#include "lua.hpp" //------定义相关的全局函数------
//创建对象
int lua_create_new_student(lua_State* L); //get/set函数
int lua_get_name(lua_State* L);
int lua_set_name(lua_State* L);
int lua_get_age(lua_State* L);
int lua_set_age(lua_State* L); //打印函数
int lua_print(lua_State* L); //------注册全局函数供Lua使用------
static const luaL_Reg lua_reg_student_funcs[] = {
{ "create", lua_create_new_student },
{ "get_name", lua_get_name },
{ "set_name", lua_set_name },
{ "get_age", lua_get_age },
{ "set_age", lua_set_age },
{ "print", lua_print },
{ NULL, NULL },
}; int luaopen_student_libs(lua_State* L);

②实现文件StudentRegFuncs.cpp

 #include "StudentRegFuncs.h"

 int lua_create_new_student(lua_State* L)
{
//创建一个对象指针放到stack里,返回给Lua中使用
Student** s = (Student**)lua_newuserdata(L, sizeof(Student*));
*s = new Student();
return ;
} int lua_get_name(lua_State* L)
{
//得到第一个传入的对象参数(在stack最底部)
Student** s = (Student**)lua_touserdata(L, );
luaL_argcheck(L, s != NULL, , "invalid user data"); //清空stack
lua_settop(L, ); //将数据放入stack中,供Lua使用
lua_pushstring(L, (*s)->get_name().c_str()); return ;
} int lua_set_name(lua_State* L)
{
//得到第一个传入的对象参数
Student** s = (Student**)lua_touserdata(L, );
luaL_argcheck(L, s != NULL, , "invalid user data"); luaL_checktype(L, -, LUA_TSTRING); std::string name = lua_tostring(L, -);
(*s)->set_name(name); return ;
} int lua_get_age(lua_State* L)
{
Student** s = (Student**)lua_touserdata(L, );
luaL_argcheck(L, s != NULL, , "invalid user data"); lua_pushinteger(L, (*s)->get_age()); return ;
} int lua_set_age(lua_State* L)
{
Student** s = (Student**)lua_touserdata(L, );
luaL_argcheck(L, s != NULL, , "invalid user data"); luaL_checktype(L, -, LUA_TNUMBER); (*s)->set_age((unsigned)lua_tointeger(L, -)); return ;
} int lua_print(lua_State* L)
{
Student** s = (Student**)lua_touserdata(L, );
luaL_argcheck(L, s != NULL, , "invalid user data"); (*s)->print(); return ;
} int luaopen_student_libs(lua_State* L)
{
luaL_newlib(L, lua_reg_student_funcs);
return ;
}

③ C++和Lua之间的交互是通过lua_newuserdata创建出来的内存块进行交互的

LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);

这个函数分配一块指定大小的内存块, 把内存块地址作为一个完全用户数据压栈, 并返回这个地址。 宿主程序可以随意使用这块内存。

④注意传入参数的检查宏luaL_argcheck

 #define luaL_argcheck(L, cond,arg,extramsg)    \
((void)((cond) || luaL_argerror(L, (arg), (extramsg))))

如果cond条件不为true,则抛出一个错误报告调用的 C 函数的第 arg 个参数的问题。

⑤类型检查函数luaL_checktype

LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);

检查函数的第 arg 个参数的类型是否是 t。

3.将对应的全局函数注册到Lua中

①加入到注册模块列表中去

 static const luaL_Reg lua_reg_libs[] = {
{ "base", luaopen_base }, //系统模块
{ "Student", luaopen_student_libs}, //模块名字Student,注册函数luaopen_student_libs
{ NULL, NULL }
};

②注册到Lua中

 //注册让lua使用的库
const luaL_Reg* lua_reg = lua_reg_libs;
for (; lua_reg->func; ++lua_reg){
luaL_requiref(L, lua_reg->name, lua_reg->func, );
lua_pop(L, );
}

4.在Lua中进行调用(Student为模块名)

 local student_obj = Student.create()
Student.set_name(student_obj,"Jack")
Student.print(student_obj)

可以看到,调用的方式需要使用模块名,并且第一个参数为创建的对象,和我们熟悉的面向对象的调用方式不一样。

Lua中面向对象的实现在下一节《Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类》。

Lua和C++交互系列:

Lua和C++交互 学习记录之一:C++嵌入脚本

Lua和C++交互 学习记录之二:栈操作

Lua和C++交互 学习记录之三:全局值交互

Lua和C++交互 学习记录之四:全局table交互

Lua和C++交互 学习记录之五:全局数组交互

Lua和C++交互 学习记录之六:全局函数交互

Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块

Lua和C++交互 学习记录之八:C++类注册为Lua模块

Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

Lua和C++交互 学习记录之八:C++类注册为Lua模块的更多相关文章

  1. Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...

  2. Lua和C++交互 学习记录之七:C++全局函数注册为Lua模块

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  3. Lua和C++交互 学习记录之六:全局函数交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  4. Lua和C++交互 学习记录之五:全局数组交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  5. Lua和C++交互 学习记录之四:全局table交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  6. Lua和C++交互 学习记录之三:全局值交互

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  7. Lua和C++交互 学习记录之二:栈操作

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  8. Lua和C++交互 学习记录之一:C++嵌入脚本

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 1 ...

  9. MyBatis 学习记录3 MapperMethod类

    主题 之前学习了一下MapperProxy的生产过程,自定义Mapper类的对象是通过动态代理生产的,调用自定义方法的时候实际上是调用了MapperMethod的execute方法:mapperMet ...

随机推荐

  1. JavaScript之BOM对象

    JavaScript bom对象 BOM对象 window对象 所有浏览器都支持 window 对象.概念上讲.一个html文档对应一个window对象.功能上讲: 控制浏览器窗口的.使用上讲: wi ...

  2. spring 配置文件属性设置默认值以及读取环境变量值

    在 Spring 中为 javabean 注入属性文件中的属性值一般人都知道的,可以通过 org.springframework.beans.factory.config.PropertyPlaceh ...

  3. Selenium android driver

    selenium android « s « Jar File Download http://www.java2s.com/Code/Jar/s/selenium-android.htm How t ...

  4. Python 数据分析 - 索引和选择数据

    loc,iloc,ix三者间的区别和联系 loc .loc is primarily label based, but may also be used with a boolean array. 就 ...

  5. tp框架中 关于数据库mysql 的一些疑点知识

    mysql创建索引, 通常是在 创建表的 同时/时候, 就创建了 即使是在win下, 用命令行操作数据库 , 也要比 图形界面的鼠标操作快得多 索引的类型有: unique, fulltext索引, ...

  6. 【问题解决:时区】连接MySQL时错误The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone

    问题描述: MySQL升级到8.0.11之后连接数据库报错: Your login attempt was not successful, try again. Reason: Could not g ...

  7. c# 之partial(分部代码和分部类)

    using System; namespace Partial { class Program { static void Main(string[] args) { A a = new A(); } ...

  8. (zhuan) Attention in Long Short-Term Memory Recurrent Neural Networks

    Attention in Long Short-Term Memory Recurrent Neural Networks by Jason Brownlee on June 30, 2017 in  ...

  9. (zhuan) How to Train Neural Networks With Backpropagation

    this blog from: http://blog.demofox.org/2017/03/09/how-to-train-neural-networks-with-backpropagation ...

  10. Vue内置的Component标签用于动态切换组件

    html <div id="app"> <component :is="cut"></component> <butt ...