游戏开发:移植golang共享库 for lua

一些奇奇怪怪的尝试 :)随笔记录下

将golang模块导出为共享库供lua使用(一般用于功能模块适配和迁移),这里给出一个借助c语言实现中间层通信的方案(不要问我为什么不使用ffi)。

假设使用go实现底层模块core,export相关API(如下例的G_Signature)供外部使用,这里是被C层使用。那么需要将go模块编译成共享库,然后在C代码中调用该共享库中的函数。

// core.go

package main

import "C"
import "fmt"

const SIGNATURE = "LINXX"
const VERSION = "0.1"

//export G_Signature
func G_Signature() *C.char {
    raw_signature := fmt.Sprintf("%s [V-%s]", SIGNATURE, VERSION)
    return C.CString(raw_signature)
}

func main() {
}

# 编译生成共享库 libcore.so
go build -o libcore.so -buildmode=c-shared core.go

c层担任转发调用请求的责任,编译生成共享库提供给lua使用,那么c需要遵循c-lua的通信格式实现。如下:

//lua-transit.c

#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>

#include <lua.h>
#include <lauxlib.h>

// 定义Golang模块中的G_Signature函数
extern char * G_Signature();

int
lsignature(lua_State *L) {
    // 调用Golang模块中的G_Signature函数
    char * sign = G_Signature();
    printf("signature: %s\n", sign);
    return 0;
}

LUAMOD_API int
luaopen_transit(lua_State *L) {
    luaL_checkversion(L);

    luaL_Reg l[] = {
        { "signature", lsignature },
        { NULL, NULL },
    };
    luaL_newlib(L, l);

    return 1;
}

# 编译生成共享库 transit.so
gcc -g -Wall lua-transit.c -o transit.so -fPIC --shared -I./3rd/lua -L. -lcore -lpthread -ldl -Wl,-rpath=.

lua层通过require c-lib实现对模块的使用;

local transit = require("transit")
transit.signature()

方案评估:

性能开销:这里有两层交互造成的性能开销,go和c的交互、c与lua的交互。

posted @ 2024-03-23 14:25  linxx-  阅读(41)  评论(0编辑  收藏  举报