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 = test2SRCS = $(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 scriptif (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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
extern "C" {#include "lua.h"#include "lauxlib.h"#include "lualib.h"#include <stdint.h>// 要被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 scriptif (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,执行成功。