上篇文章完成了在lua中调用c/c++函数,现在来实现在c/c++中调用lua函数。

首先完成lua代码,创建sum.lua:

function add(x, y)
 return x + y;
end

为了在c中调用lua中的add函数,首先需要把函数压入堆栈,然后把函数的参数压入堆栈,然后执行函数,最后从栈中获取函数返回值。先看看下面的代码:

#include <iostream>

using namespace std;

extern "C" {
 #include "lua.h"
 #include "lualib.h"
 #include "lauxlib.h"
};

static lua_State *L = NULL;

int ladd(int x, int y) {
 int sum;

 lua_getglobal(L, "add");
 lua_pushinteger(L, x);
 lua_pushinteger(L, y);
 lua_call(L, 2, 1);

 sum = (int)lua_tointeger(L, -1);

 lua_pop(L, 1);

 return sum;
}

int main() {
 L = lua_open();
 luaL_openlibs(L);
 luaL_dofile(L, "sum.lua");
 int sum = ladd(10, 20);
 cout << "sum=" << sum << endl;

 lua_close(L);

 return 0;
}

在ladd函数中执行了lua中的add函数,首先看lua_getglobal函数:

void lua_getglobal (lua_State *L, const char *name);

把全局变量 name 里的值压入堆栈。这个是用一个宏定义出来的:

#define lua_getglobal(L,s)  lua_getfield(L, LUA_GLOBALSINDEX, s)

这里lua_getglobal(L, “add”)把add函数压入堆栈,接着把x和y参数压入堆栈,然后调用lua_call执行add函数,关于lua_call函数:

void lua_call (lua_State *L, int nargs, int nresults);

它的功能是调用一个函数,需要遵循以下协议: 首先,要调用的函数应该被压入堆栈;接着把需要传递给这个函数的参数按正序压栈; 这是指第一个参数首先压栈。 最后调用一下lua_call; nargs 是你压入堆栈的参数个数。 当函数调用完毕后,所有的参数以及函数本身都会出栈。 而函数的返回值这时则被压入堆栈。 返回值的个数将被调整为 nresults 个, 除非 nresults 被设置成 LUA_MULTRET。 在这种情况下,所有的返回值都被压入堆栈中。 Lua 会保证返回值都放入栈空间中。 函数返回值将按正序压栈(第一个返回值首先压栈), 因此在调用结束后,最后一个返回值将被放在栈顶。
这里lua_call(L, 2, 1)是指函数有两个参数和一个返回值。
lua_tointeger(L, -1):表示从栈顶取得返回值。
lua_pop(L, 1):表示从堆栈中弹出一个元素,因为此时add函数已经执行完毕,参数和函数本身已经出栈,堆栈中只有返回值。
main函数中的代码跟上篇博客差不多,就不过多解释了。

ctrl+f5,最终运行结果如下:

lua面向对象模拟简介

lua不是面向对象语言,但可以通过表(table)和元表(metatable)来模拟。table 是 lua 中唯一的一种数据结构,它可以用来描述原始的数组、符号表、集合、 记录、...

阅读全文

在lua中调用c/c++函数

lua是一种轻量级的脚本语言,用来扩展c和c++非常好,在游戏开发中使用很普遍。 首先下载lua,因为我是在win7下,所以我这里下载了luaforwindows,安装到F:\Lu...

阅读全文

c++ 拷贝构造函数

1. 什么是拷贝构造函数 用c++ 创建一个空类的时候,编译器会默认为这个类创建:默认构造函数、析构函数、拷贝构造函数、赋值构造函数。 如: class A{ publi...

阅读全文

欢迎留言