luajit FFI簡單使用教程 一

2021-12-30 02:45:03 字數 3415 閱讀 2763

本文參考了luajit的官方文件編寫。文件的結構也基本上是按照官網的來。luajit ffi是乙個簡化的呼叫c庫函式的途徑。目的是簡化lua和c語言之間呼叫的繁瑣的push和pop。如果你已經有乙個c語言編寫的乙個庫了,可以不改**的前提下,使用lua直接呼叫。

先使用c編寫乙個工程,對外部提供乙個函式

int c_add(int a, int b);編寫makefile將其編譯成乙個libc_utils.so庫檔案出來。

在lua中定義這個c函式並且載入這個so庫。

local ffi = require("ffi")

ffi.cdef[[

int c_add(int a,int b);

]]local cutils = ffi.load('libc_utils')

print(cutils.c_add(200,50))如果是在windows版本上,可以直接來執行這個命令:

local ffi = require("ffi")

ffi.cdef[[

int messageboxa(void *w, const char *txt, const char *cap, int type);

]]ffi.c.messageboxa(nil, "hello world!", "test", 0)將會直接調出乙個dialog出來。

在c庫裡面定義計算向量相關的函式。我們在**裡面實現乙個向量的點

點乘(dot product)

幾何意義:

a·b = |a| |b| cos(θ).

θ是向量a和向量b見的夾角。

計算公式:

v1( x1, y1) v2(x2, y2) = x1*x2 + y1*y2

typedef struct position;

int dot_produce(position *a, position *b);

int dot_produce(position *a, position *b) local ffi = require("ffi")

ffi.cdef[[

typedef struct position;

int dot_produce(position *a, position *b);

]]local cutils = ffi.load('libc_utils')

local pos = ffi.new("position[?]", 2)

pos[0].x=10

pos[0].y=10

pos[1].x=500

pos[1].y=300

print(cutils.dot_produce(pos[0],pos[1]))local ffi = require("ffi")

1 ffi.cdef[[

unsigned long compressbound(unsigned long sourcelen);

int compress2(uint8_t *dest, unsigned long *destlen,

const uint8_t *source, unsigned long sourcelen, int level);

int uncompress(uint8_t *dest, unsigned long *destlen,

const uint8_t *source, unsigned long sourcelen);

]]2 local zlib = ffi.load(ffi.os == "windows" and "zlib1" or "z")

local function compress(txt)

3 local n = zlib.compressbound(#txt)

local buf = ffi.new("uint8_t[?]", n)

4 local buflen = ffi.new("unsigned long[1]", n)

local res = zlib.compress2(buf, buflen, txt, #txt, 9)

assert(res == 0)

5 return ffi.string(buf, buflen[0])

endlocal function uncompress(comp, n)

local buf = ffi.new("uint8_t[?]", n)

local buflen = ffi.new("unsigned long[1]", n)

local res = zlib.uncompress(buf, buflen, comp, #comp)

assert(res == 0)

return ffi.string(buf, buflen[0])

end-- ****** test code.

local txt = string.rep("abcd", 1000)

print("uncompressed size: ", #txt)

local c = compress(txt)

print("compressed size: ", #c)

local txt2 = uncompress(c, #txt)

assert(txt2 == txt)1.將zlib中的函式方法都定義到ffi介面中;

2.開始載入zlib庫的c庫檔案;

3.通過compressbound函式估算壓縮包結果的size;並且new一塊n大小的記憶體。

4.新建乙個unsigned long的變數用於提供給compress2函式中作為返回,壓縮之後記憶體塊的長度。

呼叫compress2函式,將記憶體塊加壓。

5.將返回的記憶體塊通過ffi.string轉換成lua中的記憶體塊。

後面的是他的逆過程。

在這段**裡面還是演示了一些功能:

關於ffi.new的用法。這個裡面都演示了如何建立一塊buf,如何建立一塊記憶體,並且得到他的位址。

關於ffi.string,這個模組是用於將記憶體塊和lua的string做轉換時使用。

local ffi = require("ffi")

ffi.cdef[[

typedef struct point_t;

]]local point

local mt = ,

}point = ffi.metatype("point_t", mt)

local a = point(3, 4)

print(a.x, a.y) --> 3 4

print(#a) --> 5

print(a:area()) --> 25

local b = a + point(0.5, 8)

print(#b) --> 12.5這個就是在lua裡面載入乙個c語言的struct,並且在這個物件裡面繫結上lua的實現方法。這個其實很奇妙的乙個功能,今後如果乙個c庫,想做成物件導向就能通過這個調配一下就好了。

GIThub簡單使用教程

github是乙個基於git的 託管平台,付費使用者可以建私人倉庫,我們一般的免費使用者只能使用公共倉庫,也就是 要公開。對於一般人來說公共倉庫就已經足夠了,而且我們也沒多少 來管理,o o 下面是我總結的一些簡單使用方法,供初學者參考。要想使用github第一步當然是註冊github賬號了。之後就...

git簡單使用教程

github是乙個基於git的 託管平台,付費使用者可以建私人倉庫,我們一般的免費使用者只能使用公共倉庫,也就是 要公開。對於一般人來說公共倉庫就已經足夠了,而且我們也沒多少 來管理,o o 下面是我總結的一些簡單使用方法,供初學者參考。要想使用github第一步當然是註冊github賬號了。之後就...

github簡單使用教程

在文章中插入 總是出現git和後面的不在一行中的情況。試了很多種辦法,都沒有搞定,搞得我很無語。大家就湊合著看吧。如果哪位大神知道如何解決,還請不吝賜教啊!github是乙個基於git的 託管平台,付費使用者可以建私人倉庫,我們一般的免費使用者只能使用公共倉庫,也就是 要公開。對於一般人來說公共倉庫...