LUA函数和C函数的相互调用
2013-07-29 10:56
579 查看
1. 简介LUA和C之间的函数调用也是基于上一节提到的栈。
请求LUA函数(指针)入(GLOBAL)栈。
将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。
告知LUA虚拟机入栈参数的个数、函数返回值的个数,并调用此LUA函数。
从栈定获得返回值,先返回的先入栈,然后将返回值显式出栈。
int functionName (lua_State* L) {....; return 1;}
这样的函数被是一个合法的lua_CFunction类型,将函数注册到LUA虚拟机中以后,就可以在LUA中以普通LUA函数的方式被调用。注册一个C函数的步骤如下:
声明并定义一个满足上述模型的函数 (eg. myFunInC)
用字符串为此C函数取一个名称并入栈(eg. myFunInLua)
将函数(指针)入栈
调用LUA库的注册函数功能,将上述的名称与函数指针关联
这样就可以在LUA中用myFunInLua()来调用C中的int myFunInC()了
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//初始化LUA虚拟机
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void InitLuaState(lua_State* L)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Load Libraries */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_base(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_table(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaL_openlibs(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_string(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_math(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int call_lua_function(void)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
const char* szInParam = "This is an [IN] parameter";
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
const int iParam1 = 20, iParam2 = 50;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "=================================" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "02_Call_Function" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "=================================" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "This demo calls functions in LUA scripts." << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 1:" << szInParam << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 2:" << iParam1 << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 3:" << iParam2 << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "---------------------------------" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "#OUTPUTS#" << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_State* L = lua_open();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
InitLuaState(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int iError;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Load Script */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = luaL_loadfile(L, "../test02.lua");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Load script FAILED!"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 1;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Run Script */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = lua_pcall(L, 0, 0, 0);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "pcall FAILED"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< iError
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 1;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Push a FUNCTION_VAR to STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_getglobal(L, "fnex2");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Push PARAMETERS to STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushstring(L, szInParam);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushnumber(L, iParam1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushnumber(L, iParam2);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Call FUNCTION in LUA */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = lua_pcall( L, //VMachine
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
3, //Argument Count
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
2, //Return Value Count
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
0 );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "pcall FAILED"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< iError
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Check Return Value Types */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (lua_isstring(L, -1) && lua_isnumber(L, -2))
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Ret_1(string): " << lua_tostring(L, -1) << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Rec_2(double): " << lua_tonumber(L, -2) << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Wrong Return Values" << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* POP STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pop(L,2); //只需要清理Return Value,pcall调用的入栈参数会自动清理
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 0;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define CallLuaFunc(FuncName, Params, Results)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_getglobal (g_pLuaState, FuncName);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_call (g_pLuaState, Params, Results);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
通过lua_getglobal请求函数(指针)入栈,然后将函数参数按声明顺序入栈,调用lua_pcall执行函数。lua_pcall的第一个参数 指向LUA虚拟机,第二个参数表示栈顶有多少个函数参数,第三个参数表示此函数将返回几个值。(pcall自动清理入栈的参数,返回值则需要手动 pop。)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_pushstring(L, "rmath");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_pushcfunction(L, RMath_LUA);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_settable(L, LUA_GLOBALSINDEX);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
函数名入栈
lua_CFunction类型的函数指针入栈
调用lua_settable注册函数
这样就可以在lua脚本中调用rmath()函数了。
1.1 从C程序调用LUA函数
LUA的函数和普通变量一样也是First Class Variable类型,可以看作函数指针变量参与栈操作。因此调用过程分为如下几个步骤:请求LUA函数(指针)入(GLOBAL)栈。
将函数需要的参数入栈,入栈顺序按照参数被声明的顺序。
告知LUA虚拟机入栈参数的个数、函数返回值的个数,并调用此LUA函数。
从栈定获得返回值,先返回的先入栈,然后将返回值显式出栈。
1.2 从LUA脚本调用C函数
LUA没有提供PYTHON那样丰富的类库,因此复杂的功能需要在C程序中定义好,然后通过lua决定调用时机。在LUA库中定义了可以被LUA虚拟机识别的C函数模型:int functionName (lua_State* L) {....; return 1;}
这样的函数被是一个合法的lua_CFunction类型,将函数注册到LUA虚拟机中以后,就可以在LUA中以普通LUA函数的方式被调用。注册一个C函数的步骤如下:
声明并定义一个满足上述模型的函数 (eg. myFunInC)
用字符串为此C函数取一个名称并入栈(eg. myFunInLua)
将函数(指针)入栈
调用LUA库的注册函数功能,将上述的名称与函数指针关联
这样就可以在LUA中用myFunInLua()来调用C中的int myFunInC()了
2. 从C调用LUA函数示例
在下面的代码中,我们调用了LUA脚本中的fnEx2函数,返回值从栈中取得,并且要手动出栈。这里,入栈的函数参数会由pcall自动清理。2.1 LUA测试脚本代码
function fnex2(str_a, num_b, num_c)
print(str_a);
return num_b*100 + num_c*10, "Thank you";
end;
2.2 VC代码
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
//初始化LUA虚拟机
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
void InitLuaState(lua_State* L)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Load Libraries */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_base(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_table(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaL_openlibs(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_string(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
luaopen_math(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
int call_lua_function(void)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
const char* szInParam = "This is an [IN] parameter";
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
const int iParam1 = 20, iParam2 = 50;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "=================================" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "02_Call_Function" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "=================================" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "This demo calls functions in LUA scripts." << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 1:" << szInParam << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 2:" << iParam1 << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "Argument 3:" << iParam2 << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "---------------------------------" << endl
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< "#OUTPUTS#" << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_State* L = lua_open();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
InitLuaState(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
int iError;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Load Script */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = luaL_loadfile(L, "../test02.lua");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Load script FAILED!"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 1;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Run Script */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = lua_pcall(L, 0, 0, 0);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "pcall FAILED"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< iError
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 1;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Push a FUNCTION_VAR to STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_getglobal(L, "fnex2");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Push PARAMETERS to STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushstring(L, szInParam);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushnumber(L, iParam1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pushnumber(L, iParam2);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Call FUNCTION in LUA */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
iError = lua_pcall( L, //VMachine
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
3, //Argument Count
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
2, //Return Value Count
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
0 );
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (iError)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "pcall FAILED"
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< lua_tostring(L, -1)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< iError
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
<< endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* Check Return Value Types */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if (lua_isstring(L, -1) && lua_isnumber(L, -2))
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Ret_1(string): " << lua_tostring(L, -1) << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Rec_2(double): " << lua_tonumber(L, -2) << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
else
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cout << "Wrong Return Values" << endl;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* POP STACK */
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_pop(L,2); //只需要清理Return Value,pcall调用的入栈参数会自动清理
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_close(L);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return 0;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
2.3 工具
下面的宏可以简化调用lua函数的代码:![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
#define CallLuaFunc(FuncName, Params, Results)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_getglobal (g_pLuaState, FuncName);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
lua_call (g_pLuaState, Params, Results);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
3. 从LUA调用C函数示例
在下面的例子中,我们注册一个名为rmath的LUA函数,他在C中的函数名为RMath_LUA()3.1 LUA脚本代码
print (">>> LUA程序开始运行了 ");
![]()
function fnex3(num_a, num_b)
local c = rmath(num_a, num_b);
print("LUA PRINTTING:", c);
return c;
end;
3.2 VC程序代码
//LUA脚本调用C函数
int call_c_function(void)
![]()
...{
int iArg1 = 3, iArg2 = 10, iError;
cout << "=================================" << endl
<< "下面的程序演示从LUA脚本中调用C函数" << endl
<< "Argument 1:" << iArg1 << endl
<< "Argument 2:" << iArg2 << endl
<< "---------------------------------" << endl
<< "#OUTPUTS#" << endl;
lua_State* L = lua_open();
InitLuaState(L);
![]()
iError = luaL_loadfile(L, "../test03.lua");
if (iError) cout << "载入脚本失败" << endl;
![]()
iError = lua_pcall(L, 0, 0, 0);
if (iError) cout << "执行LUA脚本失败" << endl;
![]()
![]()
/**//* 将C函数(指针)压栈 */
lua_pushstring(L, "rmath");
lua_pushcfunction(L, RMath_LUA);
lua_settable(L, LUA_GLOBALSINDEX);
![]()
![]()
/**//* LUA函数也是变量(指针),可以压入栈 */
lua_getglobal(L, "fnex3");
![]()
![]()
/**//* 将提供给LUA函数的参数入栈 */
lua_pushnumber(L, iArg1);
lua_pushnumber(L, iArg2);
![]()
![]()
/**//* 调用LUA函数(pcall函数会自动清除入栈的变量) */
int Error = lua_pcall( L, //虚拟机指针
2, //2个参数
1, //1个返回值
0 );
![]()
if (Error) cout << "pcall调用fnex3函数失败" << endl;
![]()
![]()
/**//* 检验返回值类型 */
if (lua_isnumber(L, -1))
![]()
...{
cout << "有1个(double)返回值 = "
<< lua_tonumber(L, -1)
<< endl;
}
![]()
![]()
/**//* 将LUA函数返回值出栈 */
lua_pop(L, 1);
lua_close(L);
return 0;
}
![]()
//可供LUA调用的C函数原型
int RMath_LUA(lua_State* L)
![]()
...{
if (!lua_isnumber(L, 1))
![]()
...{
lua_pushstring(L, "Arg_1不是数字");
lua_error(L);
}
![]()
if (!lua_isnumber(L, 2))
![]()
...{
lua_pushstring(L, "Arg_2不是数字");
lua_error(L);
}
![]()
![]()
/**//* GET ARGUMENT FROM STACK */
double a = lua_tonumber(L, 1);
double b = lua_tonumber(L, 2);
![]()
![]()
/**//* PUSH RESULT TO STACK */
lua_pushnumber(L, a * b);
![]()
![]()
/**//* COUNT OF RETURN VARS*/
return 1;
}
4. 程序解释
4.1 调用LUA脚本中的函数
调用LUA脚本函数主要用到如下几个LUA库函数:![]()
/**//* Push a FUNCTION_VAR to STACK */
lua_getglobal(L, "fnex2");
![]()
![]()
/**//* Push PARAMETERS to STACK */
lua_pushstring(L, szInParam);
lua_pushnumber(L, iParam1);
lua_pushnumber(L, iParam2);
![]()
![]()
/**//* Call FUNCTION in LUA */
iError = lua_pcall( L,3,2,0);
通过lua_getglobal请求函数(指针)入栈,然后将函数参数按声明顺序入栈,调用lua_pcall执行函数。lua_pcall的第一个参数 指向LUA虚拟机,第二个参数表示栈顶有多少个函数参数,第三个参数表示此函数将返回几个值。(pcall自动清理入栈的参数,返回值则需要手动 pop。)
4.2 从LUA调用C函数
主要用到如下几个函数,为求方便您也可以自己定义这样的一个宏。![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_pushstring(L, "rmath");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_pushcfunction(L, RMath_LUA);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
lua_settable(L, LUA_GLOBALSINDEX);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
函数名入栈
lua_CFunction类型的函数指针入栈
调用lua_settable注册函数
这样就可以在lua脚本中调用rmath()函数了。
相关文章推荐
- LUA函数和C函数的相互调用
- [LUA学习笔记03]LUA函数和C函数的相互调用
- 简单C++调用lua函数及C++和lua相互函数调用小例子
- 汇编函数与C函数的相互调用(1)
- C函数和C++函数相互调用
- 简单C++调用lua函数及C++和lua相互函数调用小例子
- 汇编函数与C函数的相互调用(2)
- LUA和C之间的函数相互调用
- 简单C++调用lua函数及C++和lua相互函数调用小例子
- C函数和C++函数相互调用
- C函数和C++函数相互调用的问题(★firecat推荐★)
- 汇编函数与C函数的相互调用
- 简单C++调用lua函数及C++和lua相互函数调用小例子
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
- Cocos2d-x下Lua调用自定义C++类和函数的最佳实践
- Lua教程(二十):Lua调用C函数
- 编写LUA 可调用的C 函数技巧
- 使用tolua++实现C++与LUA相互调用
- asm基础——asm函数和c++函数之间的相互调用
- Lua脚本调用C函数小结