本文參考了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的 託管平台,付費使用者可以建私人倉庫,我們一般的免費使用者只能使用公共倉庫,也就是 要公開。對於一般人來說公共倉庫...