lua中调用C++函数

我们产品中提供了很多lua-C API给用户在lua中调用,之前一直没用深究其实现原理,只是根据已有的代码在编码。显然这不是一个好的习惯,没用达到知其所以然的目的。

一、基本原理

将C++函数编译成动态链接库,然后在lua中require,通过下面的示例进行详解。

#ifdef __cplusplus
extern "C" {
#endif
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
#ifdef __cplusplus
}
#endif static int add (lua_State *L)
#ifdef __cplusplus
extern "C" {
#endif
#include<lua.h>
#include<lualib.h>
#include<lauxlib.h>
#ifdef __cplusplus
}
#endif
/**
要写一个lua中可以调用的函数,一般需要三个步骤,
第一步:定义函数,而且要遵守一定的规则,即
参数只能有一个(lua_State*),返回值也只能为
整型int,本例中static关键字可以不写。
*/
static int add (lua_State *L)
{
double op1 = lua_tonumber(L, -1);
double op2 = lua_tonumber(L, -2);
lua_pushnumber(L, op1+op2);
return 1;
} /**
第二步:列出所有的本模块中供lua调用的函数,为下
面的注册做准备
*/
static luaL_Reg myfuncs[] = {
{"add", add},
{NULL, NULL}
}; /**
第三步:注册函数到一个lua table中去。
*/
extern "C" int luaopen_mytestlib(lua_State *L)
{
luaL_register(L, "mytestlib", myfuncs);
return 1;
}

二、编译

$ g++ lua_call_cplusplus_function.cc -o mytestlib.so -shared -fPIC -I /usr/include/lua5.1/

三、运行结果

$ lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require("mytestlib")
> print(mytestlib.add(1,2))
3

四、注意事项

  • luaL_register在lua5.2中被移除了,如果使用lua5.3编译会报如下错误
$ g++ mytestlib.cc -o test.so -shared -fPIC -I /home/wuman/下载/lua-5.3.2/src
mytestlib.cc: In function ‘int luaopen_test(lua_State*)’:
mytestlib.cc:21:34: error: ‘luaL_register’ was not declared in this scope
luaL_register(L, "test", testlib);
  • luaopen_mytestlib这个 extern "C"是必须的,否则require时会报错:
$ lua
Lua 5.1.5 Copyright (C) 1994-2012 Lua.org, PUC-Rio
> require("mytestlib")
error loading module 'mytestlib' from file './mytestlib.so':
./mytestlib.so: undefined symbol: luaopen_mytestlib
stack traceback:
[C]: ?
[C]: in function 'require'
stdin:1: in main chunk
[C]: ?

lua中调用C++函数的更多相关文章

  1. Lua中调用C函数

    Lua利用一个虚拟的堆栈来给C传递值或从C获取值.每当Lua调用C函数,都会获得一个新的堆栈,该堆栈初始包含所有的调用C函数所需要的参数值(Lua传给C函数的调用实参),并且C函数执行完毕后,会把返回 ...

  2. Lua中调用C函数(lua-5.2.3)

    Lua能够调用C函数的能力将极大的提高Lua的可扩展性和可用性. 对于有些和操作系统相关的功能,或者是对效率要求较高的模块,我们全然能够通过C函数来实现,之后再通过Lua调用指定的C函数. 对于那些可 ...

  3. lua如何调用C++函数

    第一步是定义函数.所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用: typedef int (*lua_CFunction) (lua_State *L); 换句话说,函数必须要以Lu ...

  4. cocos2d-x 2.2.0 如何在lua中注册回调函数给C++

    cocos2d-x内部使用tolua进行lua绑定,但是引擎并没有提供一个通用的接口让我们可以把一个lua函数注册给C++层面的回调事件.翻看引擎的lua绑定代码,我们可以仿照引擎中的方法来做.值得吐 ...

  5. Lua中调用C++方法

    目前项目,使用了Lua脚本,至于使用Lua的好处不再赘述了.于是对Tolua做了一些小小的学习,总结一下吧. 主要说一下如何在Lua中调用C++方法. Lua调用C++的桥梁,是tolua.tolua ...

  6. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  7. 关于在C#中构造函数中调用虚函数的问题

    在C#中如果存在类的继承关系,应避免在构造函数中调用虚函数.这是由于C#的运行机制造成的,原因如下: 新建一个类实例时,C#会先初始化该类(对类变量赋值,并将函数记在函数表中),然后再初始化父类.构造 ...

  8. 如何在C语言中调用Swift函数

    在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...

  9. C++ 构造函数中调用虚函数

    我们知道:C++中的多态使得可以根据对象的真实类型(动态类型)调用不同的虚函数.这种调用都是对象已经构建完成的情况.那如果在构造函数中调用虚函数,会怎么样呢? 有这么一段代码: class A { p ...

随机推荐

  1. EntityFramework使用及优化

    1. 简介 ORM框架:Object Relation Mapping,用操作对象的方式来操作数据库 其它框架:Dapper.NHibernate,首推EF,微软官方的. EF底层还是ADO.NET实 ...

  2. nginx 日志配置不生效的问题

    log_format 有个默认的日志格式: log_format combined '$remote_addr - $remote_user [$time_local] ' ' "$requ ...

  3. Codeforces Round #493 (Div. 2) A. Balloons 贪心水题

    由于是输出任意一组解,可以将价值从小到大进行排序,第一个人只选第一个,第二个人选其余的.再比较一下第一个人选的元素和第二个人所选元素和是否相等即可.由于已将所有元素价值从小到大排过序,这样可以保证在有 ...

  4. C IO programming test code

    #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl ...

  5. JS中检测数据类型的多种方法

    面试当中经常会问到检测 js 的数据类型,我在工作当中也会用到这些方法.让我们一起走起!!! 首先给大家上一个案例 console.log(typeof "langshen"); ...

  6. 使用iframe标签时如何通过jquery隐藏滚动条

    通过mouseover和mouseout事件来控制iframe的滚动条 代码如下:

  7. 紫书 习题7-13 UVa 817(dfs+栈求表达式的值)

    题目链接  点击打开链接 这道题分为两个部分, 一用搜索枚举每种可能, 二计算表达式的值, 有挺多细节需要注意 特别注意我的代码中在计算表达式的值中用到了一个!(代码枚举中的!表示不加符号, 我现在说 ...

  8. Shiro:初识Shiro及简单尝试

    Shiro 一.什么是Shiro Apache Shiro是Java的一个安全(权限)框架 作用:认证.授权.加密.会话管理.与web集成.缓存等 下载地址:http://shiro.apache.o ...

  9. 06002_Redis概述

    1.什么是Redis? (1)Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,他通过提供多种键值对数据类型类适应不同场景下的存储需求: (2)Redis是一种高级的key ...

  10. java语言MySQL批处理

    本质来讲就是使用Statement和PreStatement的addBatch()方法 代码 import java.sql.*; public class GetConnection{ public ...