Lua 与C/C++ 交互系列: Lua调用C/C++函数(2).

1、本文将使用void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n); 来讲解在Lua Code中注册C函数,其他注册方式将在下一篇文章中讲解。

When a C function is created, it is possible to associate some values with it, thus creating a C closure ;

these values are then accessible to the function whenever it is called.

To associate values with a C function, first these values should be pushed onto the stack (when there are multiple values, the first value is pushed first).

Then lua_pushcclosure is called to create and push the C function onto the stack, with the argument n telling how many values should be associated with the function.

lua_pushcclosure also pops these values from the stack.

The maximum value for n is 255.

void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n);

Pushes a new C closure onto the stack.

当C函数创建时,可以通过c closure 关联一些值,这些值被称作upvalues.

当C函数在任何时候被调用,都可以在C函数内部获取到这些值。然后参数n指定 c closure的数量。 n最大值为255个

为了关联c closure和C函数,首先把要关联的C closure压入到虚拟栈上面。

在Lua 5.1 Reference Manual  3.4 - C Closures 有详细说明。

2、第一个例子为在Lua Code中注册函数到全局变量中。

//在Lua Code中注册的函数
int  sum(lua_State *L)
{
	int top =lua_gettop(L);
	int sum =0;
	for(size_t t=top;t>0;t--)
	{
		int lnum =lua_tonumber(L,t);
		sum+=lnum;
	}
	lua_pushnumber(L,sum);
	return 1;
}
//通过lua_pushcclosure()方法来在Lua Code中注册C函数
//lua_pushcclosure()函数是Lua C API提供注册C函数最基础的。其他注册方式都是在该函数上面拓展的。
//typedef int (*lua_CFunction) (lua_State *L); 为注册C函数的标准形式
// lua_pushcclosure() 中参数n为提供闭包upvalues值的数量
void register_sum(lua_State *L)
{   lua_settop(L,0);
    int n =0;
	lua_pushcclosure (L, sum,  n);
	lua_setglobal(L,"sum");
}

在Lua Code中调用C函数,并打印结果值:

print("sample_3.lua")

local a=sum(1,2,3,4,5)

print("a:"..a)

3、下面例子,是在上面例子的基础上,增加了闭包。

//在Lua Code中注册的函数
int  sum_closure(lua_State *L)
{   //到该函数被调用时,可以通过lua_upvalueindex()函数获取到该函数的closure
	int c1 =(int)lua_tonumber(L, lua_upvalueindex(1));
	int c2 =(int)lua_tonumber(L, lua_upvalueindex(2));
	int top =lua_gettop(L);
	int sum =c1+c2;
	for(size_t t=top;t>0;t--)
	{
		int lnum =lua_tonumber(L,t);
		sum+=lnum;
	}
	//把结果值压入虚拟栈返回
	lua_pushnumber(L,sum);
	return 1;
}
//提供upvalues
void register_sum_closure(lua_State *L)
{   lua_settop(L,0);
    //与sum_closure()函数管理的closure管理的值
    lua_pushnumber(L,100);
	lua_pushnumber(L,2000);
    int n =2; //指定与sum_closure()函数管理的upvalue数量
	lua_pushcclosure (L, sum_closure,  n);
	lua_setglobal(L,"sum_closure");
}

在Lua Code中调用C函数

local c =sum_closure(1,2,3,4,5)
print("c="..c)
int main(int argc, char **argv)
{
	 //创建lua_State
	lua_State *L = lua_open();  /* create state */
	//注册标准库
	luaL_openlibs (L);
	//注册sum 函数到全局变量中 _G["sum"]
	register_sum(L);
	//注册sum_closure(),包括2个upvalue
	register_sum_closure(L);
	//执行sample_1.lua
	luaL_dofile (L, "sample_3.lua");
	lua_close(L);
	return 1;
}
时间: 2024-12-26 09:46:48

Lua 与C/C++ 交互系列: Lua调用C/C++函数(2).的相关文章

Lua 与C/C++ 交互系列: Lua调用C/C++函数(4-2)

1.本文继续讲解Lua调用C/C++函数,本文的重点是通过metatable来实现Lua Code面向对象调用注册的C函数.本文中涉及的Environment 伪索引,userdata 以及GC 垃圾回收器的内容,都是简单的讲解.不作为本文的重点,这些内容都将在以后的章节中继续讲解. 2.本文涉及的到主要知识点补充说明. 2.1 void *lua_newuserdata (lua_State *L, size_t size); 函数说明 This function allocates a ne

Lua 与C/C++ 交互系列: Lua调用C/C++函数(4-1)

1.本文将继续讲解在Lua Code中调用注册的C函数.偶在学习本文知识点时,由于知识点的遗漏,在这个上面浪费了大量时间和精力.一直都没有没明白,Lua 通过面向对象的方式是如果调用注册的C函数.在Programming In Lua一书,有对这个方面的讲解.但是当时看书,就是不理解.因为在前面的章节中,有一个重要的知识点被遗漏.在Lua 元方法中,有两个特别重要的.__index 和__newindex被我遗漏.这两个元方法特别重要,对于定义和拓展Lua的机制,基本依靠这两个. 2.本文首先由

Lua 与C/C++ 交互系列: Lua调用C/C++函数(3)

1.Lua API中提供注册C函数关键在lua_pushcclouse()函数.该函数可以在Lua Code中定义C函数. 但是Lua 提供了几个常用的宏定义,用于注册C函数. 这几个宏定义为: /#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) LUALIB_API vo

Lua 与C/C++ 交互系列: Lua调用C/C++函数(1).

在学习Lua和C/C++过程中,在这个过程花费了不少时间.总是在几个地方卡住.Programming  In Lua 和Lua 5.1 Reference Manual  为主要学习资料. 但是Lua 5.1 Reference Manual 在演化过程中,把对虚拟栈管理部分分散在不同的章节里面.Lua 5.0 Reference Manual 版本却有这一个章节.然后,后来在lua 源代码中找到了对虚拟栈管理东东.还有在Lua的不同版本中,对注册C函数也有不同的演化.比如Function lu

Lua 与C/C++ 交互系列:Light userdata翻译

利用零碎的时间,先把以后用的知识点提前准备好.最近比较忙,正在准备一篇绑定C++对象到Lua中.但是,不想轻易下手,希望做足准备. 这篇翻译来自于lua-users.org   ,原文地址. Light User Data Light userdata, like heavy userdata, are a form of userdata, which is one of the basic data types in Lua .Light userdata are characterized

Lua 与C/C++ 交互系列:注册枚举enum到Lua Code中

在Lua Code中注册C/C++的枚举非常容易,就像注册全局变量一样.我们使用枚举名称作为命名空间,来避免注册的枚举发生冲突.注册的枚举存储在全局环境(线程环境)中. 当在Lua Code中访问枚举时,通过名称来访问对应的值. sample_9.cpp   c++代码如下: //在Lua Code中注册的enum,为了避免冲突,以名称作为enumTable来存储 enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday

Lua 与C/C++ 交互系列:动态注册枚举enum到Lua Code中,在运行时在Lua Code中获取内省信息

在Lua 5.1 Reference Manual  对于Lua 值和类型的介绍.Lua是一个动态语言,在Lua中变量仅仅有值而没有类型.所以在Lua中的变量不需要声明.所以的值本身包含类型. 其实Lua 包含一种运行时类型识别,通过type()函数,可以在运行时获取值的类型. 信息来自: Lua 5.1 Reference Manual  Values and Types Lua is a dynamically typed language. This means that variable

Lua 与C/C++ 交互系列:注冊枚举enum到Lua Code中

在Lua Code中注冊C/C++的枚举很easy,就像注冊全局变量一样.我们使用枚举名称作为命名空间,来避免注冊的枚举发生冲突.注冊的枚举存储在全局环境(线程环境)中. 当在Lua Code中訪问枚举时,通过名称来訪问相应的值. sample_9.cpp   c++代码例如以下: //在Lua Code中注冊的enum,为了避免冲突,以名称作为enumTable来存储 enum Week { Monday, Tuesday, Wednesday, Thursday, Friday, Satur

lua入门之二:c/c++ 调用lua及多个函数返回值的获取

当 Lua 调用 C 函数的时候,使用和 C 调用 Lua 同样类型的栈来交互. C 函数从栈中获取她的參数.调用结束后将返回结果放到栈中.为了区分返回结果和栈中的其它的值,每一个 C 函数还会返回结果的个数(the  function  returns  (in  C)  the  number  of  results  it  is leaving on the stack.). // luacallcpp.cpp : 定义控制台应用程序的入口点. // #include "stdafx.