您的位置:首页 > 编程语言 > Lua

Calling Lua functions : using C++ language

2014-10-19 21:55 357 查看

Audience

This article was written for C++ developers that want extend your application with Lua programming Language.

这篇文章是为那些想用Lua语言扩展应用程序的C++程序员而写。

Introduction

One of the most common tasks when you use Lua in C++ application is call Lua functions, but this can be tiresome, you need use a lot of functions of LUA C API (lua_getglobal, lua_pushnumber, lua_pushstring, lua_tointeger and so on) to call one simple Lua
function. Here I will show C++ templates that can make your life easy.

调用Lua函数是在C++应用程序中使用Lua最常见的任务之一。这个工作很烦人。你需要使用许多LUA C API(lua_getglobal, lu_pushnumber, lua_pushstring, lua_tointeger等等)来调用一个简单的Lua函数。在这里,我会展示让你的工作变得轻松的C++模板。

Interface

The interface is very easy see:. Think that you have these four Lua function and you want to call in your application:

这个接口很容易明白:想想你有下面4个Lua函数,你想在你的应用程序中调用他们。

Listing 1 – Lua Functions – test.lua

--------------------------------------------------------------------------------------

var = 10;

function

sum4(a, b, c, d)
      return

a+b+c+d;
end

function

catenate(a, b)
     

return a.." and "..b;
end

function

incVar(value)
     

var = var+value;
end

function

getVar()
      return

var;
end

--------------------------------------------------------------------------------------

Then what you need to call these function is use:

然后调用这些函数,你需要使用:

LuaCall template class.

The basic way are you instantiate LuaCall with types of your Lua function receive and return, for sample:

基本的方法是你用你的Lua函数的参数和返回值的类型实例化LuaCall模板,比如:


Collapse |
Copy Code
float a = LuaCall<float, int, float, int, int>(L, "sum4").call(5, 1.5, 5, 5);

See complete sample below (listing 2).
Listing 2 – using LuaCall – main.cpp

--------------------------------------------------------------------------------------

#include

<iostream>

#include
"LuaCall.h"

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

int
main()
{

try
{    

     
lua_State *L;

     
L =
luaL_newstate();

     
if(luaL_loadfile(L,
"list1.lua")
|| lua_pcall(L,
0, 0,
0))
{
           
throw std::string(std::string(lua_tostring(L,
-1)));
     
}
           

     
std::cout
<<LuaCall<float,
int,
float, int,
int>(L,
"sum4").call(5,
1.5,
5, 5)
<< std::endl;

     
std::cout
<< LuaCall<std::string,
std::string,
std::string>(L,
"catenate").call("Renato",
"Bianca")
<< std::endl;

     
LuaCall<NullT,
int>(L,
"incVar").call(10);

     
std::cout
<< LuaCall<int>(L,
"getVar").call()
<< std::endl;

           

     
if(L
!= NULL)
     
{
           
lua_close(L);
     
}
}
catch
(const
std::string
&e)
{
     
std::cout
<< e
<< std::endl;
}

     
return 0;
}

Implementation

This is the implementation of LuaCall:

这是LuaCall的实现:

Listing 3 –LuaCall imp – LuaCall.h

--------------------------------------------------------------------------------------

template

<

typename
T1,
typename
T2
>

class 
Duo
{
};

// type that represents unused type parameters
class 
NullT
{
};

class
LuaCallBase
{

public:
     
LuaCallBase(lua_State
*luaState,
const s
1ab0b
td::string&
functionName)
     
{
           
L =
luaState;
           
lua_getglobal(L,
functionName.c_str());
     
}

protected:

     
void push(const
int &value)
     
{
           
lua_pushinteger(L,
value);
     
}

     
void push(const
float &value)
     
{
           
lua_pushnumber(L,
value);
     
}

     
void push(const
double &value)
     
{
           
lua_pushnumber(L,
value);
     
}

     
void push(const
std::string
&value)
     
{
           
lua_pushstring(L,
value.c_str());
     
}

     
void get(int
&value)
const
     
{
           
value =
lua_tointeger(L,
-1);
     
}

     
void get(float
&value)
const
     
{
           
value =
lua_tonumber(L,
-1);
     
}

     
void get(double
&value)
const
     
{
           
value =
lua_tonumber(L,
-1);
     
}

     
void get(std::string
&value)
const
     
{
           
 value =
(char*)lua_tostring(L,
-1);
     
}

     
void get(NullT
&value)
const
     
{
     
}

protected:

     
lua_State *L;
};

template
<
typename
TR,
typename
T1 =
NullT,
typename
T2 =
NullT,
typename
T3 =
NullT,
typename
T4 =
NullT
>

class 
LuaCall
     
: public
Duo<TR,
typename LuaCall<T1,T2,T3,T4,NullT>
>
     
, public
LuaCallBase
{
public:

     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
: LuaCallBase(L,
functionName)
     
{

     
}

     
TR call(T1
a1,
T2 a2,
T3 a3,
T4 a4)
     
{
           
TR returnValue;

           
push(a1);
           
push(a2);
           
push(a3);
           
push(a4);

           
if(lua_pcall(L,
4, 1,
0)
!= 0)
           
{
                 
throw std::string(std::string(lua_tostring(L,
-1)));
           
}

           
get(returnValue);

           
return returnValue;
     
}

};

template
<
typename
TR,
typename
T1,
typename
T2,
typename
T3
>

class 
LuaCall<TR,T1,T2,T3,NullT>

     
: public
Duo<TR,T1>

     
, public
LuaCallBase
{
public:
     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
:
LuaCallBase(L,
functionName)
     
{

     
}

     
TR
call(T1
a1,
T2 a2,
T3 a3)
     
{
           
TR returnValue;

           
push(a1);
           
push(a2);
           
push(a3);

           
if(lua_pcall(L,
3, 1,
0)
!= 0)
           
{
                 
throw
std::string(std::string(lua_tostring(L,
-1)));
           
}

           
get(returnValue);

           
return returnValue;
     
}
};

template
<
typename
TR,
typename
T1,
typename
T2
>

class 
LuaCall<TR,T1,T2,NullT,NullT>

     
: public
Duo<TR,T1>

     
, public
LuaCallBase
{
public:
     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
:
LuaCallBase(L,
functionName)
     
{

     
}

     
TR call(T1
a1,
T2 a2)
     
{
           
TR returnValue;

           
push(a1);
           
push(a2);

           
if(lua_pcall(L,
2, 1,
0)
!= 0)
           
{
                 
throw
std::string(std::string(lua_tostring(L,
-1)));
           
}

           
get(returnValue);

           
return returnValue;
     
}
};

template
<
typename
TR,
typename
T1
>

class 
LuaCall<TR,T1,NullT,NullT,NullT>

     
: public
Duo<TR,T1>

     
, public
LuaCallBase
{
public:
     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
:
LuaCallBase(L,
functionName)
     
{

     
}

     
TR call(T1
a1)
     
{
           
TR returnValue;

           
push(a1);

           
if(lua_pcall(L,
1, 1,
0)
!= 0)
           
{
                 
throw
std::string(std::string(lua_tostring(L,
-1)));
           
}

           
get(returnValue);

           
return returnValue;
     
}
};

template
<typename
TR>
class 
LuaCall<TR,NullT,NullT,NullT,NullT>

     
: public
Duo<TR,NullT>

     
, public
LuaCallBase
{
public:
     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
:
LuaCallBase(L,
functionName)
     
{
     
}

     
TR
call(void)
     
{
           
TR returnValue;

           
if(lua_pcall(L,
0, 1,
0)
!= 0)
           
{
                 
throw
std::string(std::string(lua_tostring(L,
-1)));
           
}

           
get(returnValue);

           
return returnValue;
     
}
};

template
<>
class 
LuaCall<NullT,NullT,NullT,NullT,NullT>

     
: public
LuaCallBase
{
public:
     
LuaCall(lua_State
*L,
const std::string&
functionName)
           
: LuaCallBase(L,
functionName)
     
{
     
}

     
void call(void)
     
{
           
if(lua_pcall(L,
0, 0,
0)
!= 0)
           
{
                 
throw std::string(std::string(lua_tostring(L,
-1)));
           
}
     
}
};

Bibliography
Roberto Ierusalimschy

Programming in Lua – 2nd ed. (http://www.inf.puc-rio.br/~roberto/pil2/)

ISBN 85-903798-2-5

David Vandevoorde - Nicolai M. Josuttis

C++ Templates - The Complete Guide

ISBN 0-201-73484-2

Lua.org
http://www.lua.org/

Mailing list
http://www.lua.org/lua-l.html

Community
http://www.lua.org/community.html

Embeddable scripting with Lua
http://www-128.ibm.com/developerworks/linux/library/l-lua.html

The Web Links listed here may not be valid in the future.


License

This article, along with any associated source code and files, is licensed under

The MIT License

原文地址

http://www.codeproject.com/Articles/17469/Calling-Lua-functions-using-C-language


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ Lua Template