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 Luafunction. 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 underThe MIT License
原文地址
http://www.codeproject.com/Articles/17469/Calling-Lua-functions-using-C-language
相关文章推荐
- Calling lua functions from .lua's using handles?
- Calling C++ Functions From Lua(lua调用c/c++)
- 《AspectC++ Language Reference》chapter 3: Match Expressions & chapter 4: Predefined Pointcut Functions
- Calling Lua function from C++
- Using Lua with C++: A short tutorial
- calling c++ function from Lua, implement sleep function
- Calling C++ DLLs from C++ Application Using VS2020
- Calling C/C++ functions from C#
- Functions(Chapter 7 of The C++ Programming Language)
- Using Lua with C++ — A short tutorial
- Calling Fortran functions from C++ by means of shared libraries
- Implementing Callback Functions Using Delegates In C++
- Calling 64-bit assembly language functions lodged inside the Delphi source code
- Using Lua with C++
- Calling API functions using C#
- Calling C++ DLLs from C++ Application Using VS2020
- Using managed reference types in C++
- The C++ Programming Language 第二章
- Using ADO from C++
- The C++ Programming Language 第六章 笔记