C语言和Lua的相互调用示例代码
本代码参考博客: https://lucasklassmann.com/blog/2019-02-02-how-to-embeddeding-lua-in-c/
/**
* @file luaLearn.c
* @brief C and Lua call Learn Demo
* @version 0.1
* @date 2022-08-19
*
* @copyright Copyright (c) 2022
*
*/
//参考文档
//https://lucasklassmann.com/blog/2019-02-02-how-to-embeddeding-lua-in-c/
#include <stdio.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
//基本的Lua和C交互的函数
int BasicLuaFunction()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
// Work with lua API
lua_close(L);
return 0;
}
//无参数调用Lua
int CallLuaFunctionWithOutArguments()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
char* pLua = "print('this is lua')";
// Work with lua API
// Here we load the string and use lua_pcall for run the code
int nLoadRet = luaL_loadstring(L, pLua);
if (nLoadRet == LUA_OK) {
if (lua_pcall(L, 0, 0, 0) == LUA_OK) {
// If it was executed successfuly we
// remove the code from the stack
lua_pop(L, lua_gettop(L));
}
}
lua_close(L);
return 0;
}
//Set Lua variable value in C function
int SetLuaVariableValueInCfunction()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
lua_pushinteger(L, 42);
lua_setglobal(L, "answer");
char* code = "print(answer)";
if (luaL_dostring(L, code) == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
lua_close(L);
return 0;
}
// Define our function, we have to follow the protocol of lua_CFunction that is
// typedef int (*lua_CFunction) (lua_State *L);
// When this function is called by Lua, the stack contains the arguments needed,
// what we need to do check if the arguments have the type that we expect.
int multiplication(lua_State* L) {
// Check if the first argument is integer and return the value
int a = luaL_checkinteger(L, 1);
// Check if the second argument is integer and return the value
int b = luaL_checkinteger(L, 2);
// multiply and store the result inside a type lua_Integer
lua_Integer c = a * b;
// Here we prepare the values to be returned.
// First we push the values we want to return onto the stack in direct order.
// Second, we must return the number of values pushed onto the stack.
// Pushing the result onto the stack to be returned
lua_pushinteger(L, c);
return 1; // The number of returned values
}
//从Lua中调用C语言编写的函数,带参数
int CallCfunctionFromLua()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
// Push the pointer to function
lua_pushcfunction(L, multiplication);
// Get the value on top of the stack
// and set as a global, in this case is the function
lua_setglobal(L, "mul");
// we can use the function `mul` inside the Lua code
char* code = "print(mul(7, 8))";
if (luaL_dostring(L, code) == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
lua_close(L);
return 0;
}
//func5.lua--> print("hello,word from lua")
//Call Lua function from lua file
int CallLuaFunctionFromLuaFile()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "luafunction.lua") == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
lua_close(L);
return 0;
}
//GetVariableValueFromLua.lua --->message = 'This message is stored inside lua code'
//从Lua文件中获取Lua变量的值
int GetVariableValueFromLuaFile()
{
lua_State* L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "GetVariableValueFromLua.lua") == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
lua_getglobal(L, "message");
if (lua_isstring(L, -1)) {
const char * message = lua_tostring(L, -1);
lua_pop(L, 1);
printf("Message from lua: %s\n", message);
}
lua_close(L);
return 0;
}
//luafunc.lua --->
/*
function my_function()
print("Hello from Function in Lua")
end
*/
int CallFunctionDefinedInLuaFile()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "LuaDefinedFunction.lua") == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
lua_getglobal(L, "my_function");
if (lua_isfunction(L, -1)) {
if (lua_pcall(L, 0, 1, 0) == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
}
lua_close(L);
return 0;
}
//Calling a Lua function in C with arguments and return value
//luaFunctionWithArguments.lua
/*
function my_function(a, b)
return a * b
end
*/
int CallFunctionDefinedInLuaFileWithArgmentsAndReturnValue()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
if (luaL_dofile(L, "luaFunctionWithArguments.lua") == LUA_OK) {
lua_pop(L, lua_gettop(L));
}
// Put the function to be called onto the stack
lua_getglobal(L, "my_function");
lua_pushinteger(L, 3); // first argument
lua_pushinteger(L, 4); // second argument
// Execute my_function with 2 arguments and 1 return value
if (lua_pcall(L, 2, 1, 0) == LUA_OK) {
// Check if the return is an integer
if (lua_isinteger(L, -1)) {
// Convert the return value to integer
int result = lua_tointeger(L, -1);
// Pop the return value
lua_pop(L, 1);
printf("Result: %d\n", result);
}
// Remove the function from the stack
lua_pop(L, lua_gettop(L));
}
lua_close(L);
return 0;
}
int CallLuaFunctionWithErrorHandling()
{
lua_State *L = luaL_newstate();
luaL_openlibs(L);
char * code = "print(return)"; // intentional error
if (luaL_dostring(L, code) != LUA_OK) {
puts(lua_tostring(L, lua_gettop(L)));
lua_pop(L, lua_gettop(L));
}
lua_close(L);
return 0;
}
int main(int argc, char** argv) {
printf("This is c main function\n");
BasicLuaFunction();
CallLuaFunctionWithOutArguments();
CallCfunctionFromLua();
CallLuaFunctionFromLuaFile();
CallFunctionDefinedInLuaFile();
CallFunctionDefinedInLuaFileWithArgmentsAndReturnValue();
CallLuaFunctionWithErrorHandling();
SetLuaVariableValueInCfunction();
GetVariableValueFromLuaFile();
return 0;
}
/*int main(int argc, char* argv[])
{
printf("This is c main function\n");
return 0;
}*/