Lua脚本如何执行主程序的C函数 - 实践

Lua Call C function

Lua脚本可以和C函数灵活的结合,Lua脚本作为控制语言,使用C函数来做性能计算部分。
Lua脚本的执行器有Lua 和 Luajit。
使用Lua执行器,可以通过C语言注册C函数到Lua State, 然后Lua脚本可以调用该C函数。

使用Luajit,支持FFI,可以支持 require(“libxxx.so”) , 通过函数符号表请求,同时Luajit也可以支持调用主程序的函数。
本文将展示Lua脚本直接调用主程序函数的例子。

主程序导出动态符号表

主程序默认是没有自定义的函数的符号的
请添加图片描述

编译选项增加 -rdynamic

就包含了自定义函数的动态符号表
请添加图片描述

Lua查找并使用C函数

引用ffi,先定义函数

local ffi = require("ffi")
-- 1. 先做C接口定义
ffi.cdef[[
bool SendMsg(const char* json_str, const char* str1, const char* str2, int pri);
int AddNumbers(int a, int b);
]]
-- 测试基本函数调用
print("\n基本函数调用:")
local result = ffi.C.SendMsg('{"temp": 25.5}', "data", "sensor", 0)
print("Send result:", result)

Makefile指定Luajit执行器

Luajit是必须的,如果是lua执行器,则不支持该操作

TARGET = test2
SRCS = $(wildcard *.cpp)
CC = g++
CFLAGS += -g -O2 -std=c++11 -I/usr/local/include/luajit-2.1/
LDFLAGS += -lyaml-cpp -L/usr/local/lib -lluajit-5.1 -ldl -rdynamic
all: $(TARGET)
$(TARGET): $(SRCS)
$(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS)
.PHONY: clean
clean:
rm $(TARGET)

C代码定义函数,执行Lua

luaL_dofile 即执行指定Lua脚本

lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Load Lua script
if (luaL_dofile(L, "advanced_ffi.lua") != LUA_OK) {
fprintf(stderr, "Error loading Lua script: %s\n", lua_tostring(L, -1));
lua_close(L);
return 1;
}
lua_close(L);

完整代码simple_ffi.cpp

#include
#include
#include
#include
extern "C" {
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include
// 要被Lua FFI调用的C函数
bool SendMsg(const char* json_str, const char* str1, const char* str2, int pri) {
printf("=== C Function Called ===\n");
printf("JSON: %s\n", json_str ? json_str : "NULL");
printf("str-1: %s\n", str1 ? str1 : "NULL");
printf("str-2: %s\n", str2 ? str2 : "NULL");
printf("Priority: %d\n", pri);
if (!json_str || !str2) {
printf("ERROR: Missing required parameters\n");
return false;
}
printf("Message sent successfully!\n");
return true;
}
int AddNumbers(int a, int b) {
printf("C function: %d + %d = %d\n", a, b, a + b);
return a + b;
}
const char* GetVersion() {
return "FFI Demo v1.0";
}
}
int main() {
printf("C Program: Functions are ready for FFI access\n");
printf("You can now run: luajit ffi_test.lua\n");
// 演示直接调用
printf("\nDirect C calls:\n");
SendMsg("{\"test\":\"data\"}", "sub", "title", 5);
printf("Add result: %d\n", AddNumbers(10, 20));
printf("Version: %s\n", GetVersion());
lua_State *L = luaL_newstate();
luaL_openlibs(L);
// Load Lua script
if (luaL_dofile(L, "advanced_ffi.lua") != LUA_OK) {
fprintf(stderr, "Error loading Lua script: %s\n", lua_tostring(L, -1));
lua_close(L);
return 1;
}
lua_close(L);
printf("All tests completed successfully.\n");
return 0;
}

测试

导出函数符号表的test2,执行成功。

请添加图片描述

posted @ 2025-09-05 22:04  yjbjingcha  阅读(13)  评论(0)    收藏  举报