mirror of
https://gitcode.com/JianFeeeee/LuaCangjia_api.git
synced 2026-09-21 09:28:17 +00:00
完成桥接层
This commit is contained in:
@ -8,7 +8,7 @@ output-type ="executable"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
||||||
[ffi.c]
|
[ffi.c]
|
||||||
luacjapi.path = "./lib/build/luacjapi"
|
luacjapi.path = "./lib/build"
|
||||||
|
|
||||||
[scripts]
|
[scripts]
|
||||||
pre-build = "cjpm run build.cj pre-build"
|
pre-build = "cjpm run build.cj pre-build"
|
||||||
|
|||||||
@ -308,7 +308,7 @@ void *init_lua_runner(const char *pathio,const char *pkgpath,int(*input)(),int(*
|
|||||||
if(pathio == NULL)
|
if(pathio == NULL)
|
||||||
{
|
{
|
||||||
errno = NAPI_LUA_MISS_REDIRECT;
|
errno = NAPI_LUA_MISS_REDIRECT;
|
||||||
return NULL;
|
goto WITHOUT_REDIRECT;
|
||||||
}
|
}
|
||||||
//装载重定向函数
|
//装载重定向函数
|
||||||
io_path->funcs.io_input = input;
|
io_path->funcs.io_input = input;
|
||||||
@ -320,7 +320,7 @@ void *init_lua_runner(const char *pathio,const char *pkgpath,int(*input)(),int(*
|
|||||||
errno = NAPI_LUA_STATE_ERROR;
|
errno = NAPI_LUA_STATE_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
WITHOUT_REDIRECT:
|
||||||
return (void*)self;
|
return (void*)self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
128
src/bridge.cj
Normal file
128
src/bridge.cj
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
package LuaCangjie_api
|
||||||
|
|
||||||
|
import std.collection.*
|
||||||
|
|
||||||
|
// ==================== FFI底层 ====================
|
||||||
|
|
||||||
|
type IOCallback = CFunc<() -> Int32>
|
||||||
|
|
||||||
|
@C
|
||||||
|
foreign func init_lua_runner(pathio: CString, pkgpath: CString, input: IOCallback, output: IOCallback): CPointer<Unit>
|
||||||
|
@C
|
||||||
|
foreign func load_lib(selfd: CPointer<Unit>, path: CString, name: CString): Int32
|
||||||
|
@C
|
||||||
|
foreign func unload_lib(selfd: CPointer<Unit>, name: CString): Int32
|
||||||
|
@C
|
||||||
|
foreign func run(selfd: CPointer<Unit>, path: CString, arg: CString): Int32
|
||||||
|
@C
|
||||||
|
foreign func cleanup(selfd: CPointer<Unit>): Int32
|
||||||
|
@C
|
||||||
|
foreign func get_errno(): Int32
|
||||||
|
@C
|
||||||
|
foreign func getresult(selfd: CPointer<Unit>): CString
|
||||||
|
@C
|
||||||
|
foreign func free_lua(selfd: CPointer<Unit>): Int32
|
||||||
|
|
||||||
|
// ==================== 工具函数 ====================
|
||||||
|
|
||||||
|
@C
|
||||||
|
func defaultIO(): Int32 {
|
||||||
|
// 默认输入回调,返回0表示成功
|
||||||
|
0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private func toCStr(s: String): CString{
|
||||||
|
if (s.isEmpty()) {
|
||||||
|
var tmp = CString(CPointer<UInt8>());
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
unsafe { LibC.mallocCString(s) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CString转String:通过 CPointer<UInt8> 构造 CString 后调用 toString()
|
||||||
|
private func toString(ptr: CString): String {
|
||||||
|
if (ptr.isNull()) { return "" }
|
||||||
|
// 将 CPointer<Int8> 强制转换为 CPointer<UInt8>
|
||||||
|
// 通过 CPointer<UInt8> 构造 CString
|
||||||
|
return ptr.toString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 异常 ====================
|
||||||
|
|
||||||
|
public class LuaError <: Exception {
|
||||||
|
public let code: Int32
|
||||||
|
public init(code: Int32, msg: String) { super(msg); this.code = code }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ==================== 主类 ====================
|
||||||
|
|
||||||
|
public class LuaRunner {
|
||||||
|
private var handle: CPointer<Unit>
|
||||||
|
private var cachedResult: String = ""
|
||||||
|
private var ioInput: IOCallback
|
||||||
|
private var ioOutput: IOCallback
|
||||||
|
//pkgpath 重定向lua状态机包搜索路径
|
||||||
|
//pathio 重定向io输出到pathio路径下
|
||||||
|
//@param output 类型function 用于lua内部触发输出时调用的回调函数
|
||||||
|
//@param input 类型function 用于lua内部触发输入时的调用的回调函数
|
||||||
|
//@brief 构造lua状态机
|
||||||
|
public init( input!: IOCallback = defaultIO, output!: IOCallback = defaultIO,pathio!: String='' , pkgpath!: String='') {
|
||||||
|
this.ioInput = input
|
||||||
|
this.ioOutput = output
|
||||||
|
var tmpio = toCStr(pathio);
|
||||||
|
var tmppkg = toCStr(pkgpath);
|
||||||
|
|
||||||
|
this.handle = unsafe { init_lua_runner(tmpio,tmppkg, input, output) }
|
||||||
|
unsafe{
|
||||||
|
LibC.free(tmpio);
|
||||||
|
LibC.free(tmppkg);
|
||||||
|
}
|
||||||
|
if (this.handle.isNull()) { throw LuaError(-1, "Init failed") }
|
||||||
|
}
|
||||||
|
|
||||||
|
~init() {
|
||||||
|
if (!this.handle.isNull()) {
|
||||||
|
unsafe { free_lua(this.handle) }
|
||||||
|
this.handle = CPointer<Unit>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func load(path: String, name: String): This {
|
||||||
|
let result = unsafe { load_lib(this.handle, toCStr(path), toCStr(name)) }
|
||||||
|
if (result != 0) {
|
||||||
|
throw LuaError(unsafe { get_errno() }, toString(unsafe { getresult(this.handle) }))
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public func unload(name: String): This {
|
||||||
|
let result = unsafe { unload_lib(this.handle, toCStr(name)) }
|
||||||
|
if (result != 0) {
|
||||||
|
throw LuaError(unsafe { get_errno() }, toString(unsafe { getresult(this.handle) }))
|
||||||
|
}
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
public func runScript(path: String, arg: String): String {
|
||||||
|
let code = unsafe { run(this.handle, toCStr(path), toCStr(arg)) }
|
||||||
|
this.cachedResult = toString(unsafe { getresult(this.handle) })
|
||||||
|
if (code != 0) { throw LuaError(unsafe { get_errno() }, this.cachedResult) }
|
||||||
|
return this.cachedResult
|
||||||
|
}
|
||||||
|
|
||||||
|
public func result(): String { this.cachedResult }
|
||||||
|
|
||||||
|
public func error(): String { toString(unsafe { getresult(this.handle) }) }
|
||||||
|
|
||||||
|
public func clear(): This {
|
||||||
|
let result = unsafe { cleanup(this.handle) }
|
||||||
|
if (result != 0) { throw LuaError(unsafe { get_errno() }, "Cleanup failed") }
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
}
|
||||||
36
src/main.cj
36
src/main.cj
@ -1,17 +1,31 @@
|
|||||||
package LuaCangjie_api
|
package LuaCangjie_api
|
||||||
|
|
||||||
@C
|
import std.console.*
|
||||||
struct lua_runner {
|
|
||||||
|
|
||||||
}
|
// ==================== @C 修饰的回调函数 ====================
|
||||||
|
|
||||||
|
|
||||||
|
// ==================== main ====================
|
||||||
|
|
||||||
foreign{
|
|
||||||
func init_lua_runner(self:CPointer<lua_runner>,pathio:CString,pkgpath:CString,io_input:CFunc<() -> Int32>,io_output:CFunc<() -> Int32>):Int32
|
|
||||||
func get_errno():Int32
|
|
||||||
func getresult(runner:CPointer<lua_runner>):CString
|
|
||||||
func run(self:CPointer<lua_runner>,path:CString,arg:CString):Int32
|
|
||||||
}
|
|
||||||
main(): Int64 {
|
main(): Int64 {
|
||||||
println("hello world")
|
try {
|
||||||
return 0
|
// 创建 LuaRunner 实例,使用 @C 函数作为回调
|
||||||
|
let runner = LuaRunner()
|
||||||
|
|
||||||
|
println("LuaRunner initialized successfully")
|
||||||
|
|
||||||
|
// 运行 test.lua 脚本,无参数传入
|
||||||
|
let result = runner.runScript("test.lua", "")
|
||||||
|
|
||||||
|
println("Script output: ${result}")
|
||||||
|
|
||||||
|
// 清理缓存(析构函数会自动释放资源)
|
||||||
|
runner.clear()
|
||||||
|
|
||||||
|
} catch (e: LuaError) {
|
||||||
|
println("Error [code=${e.code}]: ${e.message}")
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
0
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user