所有能在lua中调用的c/c++函数都必须是遵循lua定义的函数原型:typedef int (*lua_CFunction) (lua_State *L),其中返回值整型int表示,函数返回值个数。lua调用c/c++函数,他们之间的交互依然通过lua栈,而且需要认识到的是,无论是lua调用c函数,还是c/c++调用lua函数,他们之间的交互用的栈并不是全局栈,每个函数都维护着一个自己的私有栈,所有的交互数据均保存在这个私有栈中。
当lua调用c函数时,lua把所有参数都压进函数的私有栈中,并且第一个参数在栈中的位置必定为index=1,第二个参数为index=2,以此类推,的位置。c函数需要从栈中取得参数,在完成相关处理后把处理结果压入私有栈中。返回结果在理论上可以是任意数目,在c函数的最后必须返回代表结果的个数。
测试代码:
lua代码:testGlueLua.lua
myFile = io.open( "io.lua", "w" )
if myFile ~= nil then
myFile:write( "pow: ")
myFile:write( MyPow( 3, 2 ) )
end
io.close( myFile )
c++代码:test.cpp
//测试lua开发库
//1.新建一个lua_state 并初始化环境
//2.加载相关lua程序库
//3.加载执行lua文件
//4.查询要执行的函数,参数入栈
//5.执行函数
//6.从lua栈中提取返回值
#include <iostream>
extern "C" //采用c编译方式
{
#include <lua\lua.h>
#include <lua\lualib.h>
#include <lua\lauxlib.h>
}
using namespace std;
//测试lua调用c函数
//所有能在lua中调用的c函数,必须具有lua定义的原型。
//lua与c/c++之间的交互依然通过lua栈。
//--无论是lua调用c函数,还是c/c++调用lua函数,每个函数都维护了自己的私有栈,而非全局栈。
//--当lua调用c函数时,会把参数压入私有栈中,第一个参数在栈中的位置总是index=1..第二个为index=2的位置,以此类推。
//--而被调用的c函数有着固定的原型:typedef int (*lua_CFunction) (lua_State *L);,c函数从交互的私有栈中取得参数
//--并处理后同样 把结果存到私有栈中,并返回返回值的个数。
//--luaGlue函数编写:
//--1.注意检查参数类型。
//--2.注意把结果压入交互栈
//--3.并返回结果个数。
int MyPow( lua_State* L )
{
//检查两个参数类型
double a = luaL_checknumber( L, 1 );
double b = luaL_checknumber( L, 2 );
lua_pushnumber( L, pow( a, b ) );
return 1; //返回值个数
}
int main()
{
//初始化lua环境,加载了5.1版本的所有程序库
lua_State* L = lua_open();
luaL_openlibs( L );//分开加载库是io库有个bug听说
/*::luaopen_base( L );
::luaopen_io( L );
::luaopen_debug( L );
::luaopen_math( L );
::luaopen_os( L );
::luaopen_package( L );
::luaopen_string( L );
::luaopen_table( L );*/
luaL_dofile( L, "test.lua" ); //执行配置文件
int a = 1;
int b = 2;
lua_getglobal( L, "add" ); //查询函数
lua_pushnumber( L, a ); //参数压栈
lua_pushnumber( L, b );
if( lua_pcall( L, 2, 1, 0 ) != 0 ) //错误检测
{
cout <<"error running function add:" <<lua_tostring( L, -1 ) <<endl;
}
if( !lua_isnumber( L, -1 ) ) //检查返回值是否为数值
{
cout <<"add 必须返回一个数值" <<endl;
}
int c = lua_tonumber( L, -1 );
lua_pop( L, 1 ); //从栈中弹出返回值!!!
cout <<"a + b = " <<c <<endl;
/*---测试lua中调用c函数---*/
lua_pushcfunction( L, MyPow );
lua_setglobal( L, "MyPow" ); //第二个参数为lua中使用MyPow的名称
//lua_register( L, "MyPow", MyPow ); //第二个参数为lua中使用MyPow的名称
//加载执行lua文件
luaL_dofile( L, "testLuaGlue.lua" );
return 0;
}在编译运行c++程序后,可以再程序目录底下看到生成的io.lua文件:
1万+



被折叠的 条评论
为什么被折叠?



