Lua與C的交互

  • C與lua交互解釋
C和Lua的交互部分稱爲C API,C API是一個C代碼和Lua代碼進行交互的函數集,主要由如下部分組成:
一、讀取Lua全局變量的函數;
二、調用Lua函數的函數;
三、運行Lua代碼片斷的函數;
四、註冊C函數而後能夠在Lua中被調用的函數;
C語言和Lua之間的數據通訊交換,是經過在C和Lua之間創建一個虛擬的棧,幾乎全部的API調用都是對棧上的值進行操做,全部的數據交換也是經過這個棧來進行的,而這個棧是由Lua管理的,垃圾回收器知道哪一個值正在被C使用。
  • C調用lua腳本
lua腳本
width = 100
height = 101
hello = 95050

function add(a, b)
 return a + b + 100
end
main.c
#include <stdio.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"

int main(){
  lua_State *L = luaL_newstate();
 luaL_openlibs(L);

 if(luaL_loadfile(L, "test.lua") || lua_pcall(L, 0, 0, 0)){
 printf("error");
 return -1;
 }

 lua_getglobal(L, "width");
 lua_getglobal(L, "height");
 lua_getglobal(L, "hello");
 printf("width = %d\n", lua_tointeger(L, -3));
 printf("height = %d\n", lua_tointeger(L, -2));
 printf("%d\n", lua_tointeger(L, -1));

 lua_getglobal(L, "add");
 lua_pushnumber(L, 100);
 lua_pushnumber(L, 180);
 //2表明參數個數,1表明返回結果個數
  int ret = lua_pcall(L, 2, 1, 0);
 if(ret){
 //表明調用出錯
 }
 if(lua_isnumber(L, -1)){
 printf("%d", lua_tointeger(L, -1));
 }
 lua_close(L);
 return 0;
}
編譯運行腳本
gcc -lm -g -o test main.c ./liblua.a -ldl
./test
  • lua調用C的lib模塊(須要lua 5.3以上的版本支持)
mylib.c
#include <stdio.h>
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <math.h>

static int 
myadd(lua_State *L){
  int a = luaL_checknumber(L, 1);
  int b = luaL_checknumber(L, 2);
 lua_pushnumber(L, a + b);
 return 1;
}

static const struct luaL_Reg mylib [] = {
 {"add", myadd},
 {NULL, NULL}
};

int luaopen_mylib(lua_State *L){
 luaL_newlib(L, mylib);
 return 1;
}
test.lua
local lib = require "mylib"
width = 100
height = 101
hello = 95050

print(lib.add(1, 400))

function add(a, b)
 return a + b + 100
end
編譯腳本
gcc mylib.c -fPIC -shared -o mylib.so
eg:編譯註解
最主要的是GCC命令行的一個選項:
-shared該選項指定生成動態鏈接庫(讓鏈接器生成T類型的導出符號表,有時候也生成弱連
W類型的導出符號),不用該標誌外部程序沒法鏈接。至關於一個可執行文件

-fPIC:表示編譯爲位置獨立的代碼,不用此選項的話編譯後的代碼是位置相關的因此動態載
入時是經過代碼拷貝的方式來知足不一樣進程的須要,而不能達到真正代碼段共享的目的。

-L.:表示要鏈接的庫在當前目錄中

-ltest:編譯器查找動態鏈接庫時有隱含的命名規則,即在給出的名字前面加上lib,後面
加上.so來肯定庫的名稱

LD_LIBRARY_PATH:這個環境變量指示動態鏈接器能夠裝載動態庫的路徑。

固然若是有root權限的話,能夠修改/etc/ld.so.conf文件,而後調用 /sbin/ldconfig
來達到一樣的目的,不過若是沒有root權限,那麼只能採用輸出LD_LIBRARY_PATH的方法
了。
相關文章
相關標籤/搜索