luajit日记-FFI库
生活随笔
收集整理的這篇文章主要介紹了
luajit日记-FFI库
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
2019獨角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
LuaJIT?FFI?LibraryThe?FFI?library?allows?calling?external?C?functions?and?using?C?data?structures?from?pure?Lua?code.? The?FFI?library?largely?obviates?the?need?to?write?tedious?manual?Lua/C?bindings?in?C.?No?need?to?learn?a?separate?binding?language?—?it?parses?plain?C?declarations!?These?can?be?cut-n-pasted?from?C?header?files?or?reference?manuals.?It's?up?to?the?task?of?binding?large?libraries?without?the?need?for?dealing?with?fragile?binding?generators.? The?FFI?library?is?tightly?integrated?into?LuaJIT?(it's?not?available?as?a?separate?module).?The?code?generated?by?the?JIT-compiler?for?accesses?to?C?data?structures?from?Lua?code?is?on?par?with?the?code?a?C?compiler?would?generate.?Calls?to?C?functions?can?be?inlined?in?JIT-compiled?code,?unlike?calls?to?functions?bound?via?the?classic?Lua/C?API. This?page?gives?a?short?introduction?to?the?usage?of?the?FFI?library.?Please?use?the?FFI?sub-topics?in?the?navigation?bar?to?learn?more.?Motivating?Example:?Calling?External?C?Functions It's?really?easy?to?call?an?external?C?library?function:local?ffi?=?require("ffi")ffi.cdef[[int?printf(const?char?*fmt,?...);]]ffi.C.printf("Hello?%s!",?"world") So,?let's?pick?that?apart: 1.Load?the?FFI?library. 2.Add?a?C?declaration?for?the?function.?The?part?inside?the?double-brackets?(in?green)?is?just?standard?C?syntax. 3.Call?the?named?C?function?—?Yes,?it's?that?simple!?Actually,?what?goes?on?behind?the?scenes?is?far?from?simple:?③?makes?use?of?the?standard?C?library?namespace?ffi.C.?Indexing?this?namespace?with?a?symbol?name?("printf")?automatically?binds?it?to?the?standard?C?library.?The?result?is?a?special?kind?of?object?which,?when?called,?runs?the?printf?function.?The?arguments?passed?to?this?function?are?automatically?converted?from?Lua?objects?to?the?corresponding?C?types. Ok,?so?maybe?the?use?of?printf()?wasn't?such?a?spectacular?example.?You?could?have?done?that?with?io.write()?and?string.format(),?too.?But?you?get?the?idea?... So?here's?something?to?pop?up?a?message?box?on?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) Bing!?Again,?that?was?far?too?easy,?no? Compare?this?with?the?effort?required?to?bind?that?function?using?the?classic?Lua/C?API:?create?an?extra?C?file,?add?a?C?function?that?retrieves?and?checks?the?argument?types?passed?from?Lua?and?calls?the?actual?C?function,?add?a?list?of?module?functions?and?their?names,?add?a?luaopen_*?function?and?register?all?module?functions,?compile?and?link?it?into?a?shared?library?(DLL),?move?it?to?the?proper?path,?add?Lua?code?that?loads?the?module?aaaand?...?finally?call?the?binding?function.?Phew!Motivating?Example:?Using?C?Data?Structures The?FFI?library?allows?you?to?create?and?access?C?data?structures.?Of?course?the?main?use?for?this?is?for?interfacing?with?C?functions.?But?they?can?be?used?stand-alone,?too. Lua?is?built?upon?high-level?data?types.?They?are?flexible,?extensible?and?dynamic.?That's?why?we?all?love?Lua?so?much.?Alas,?this?can?be?inefficient?for?certain?tasks,?where?you'd?really?want?a?low-level?data?type.?E.g.?a?large?array?of?a?fixed?structure?needs?to?be?implemented?with?a?big?table?holding?lots?of?tiny?tables.?This?imposes?both?a?substantial?memory?overhead?as?well?as?a?performance?overhead. Here's?a?sketch?of?a?library?that?operates?on?color?images?plus?a?simple?benchmark.?First,?the?plain?Lua?version:local?floor?=?math.floorlocal?function?image_ramp_green(n)local?img?=?{}local?f?=?255/(n-1)for?i=1,n?doimg[i]?=?{?red?=?0,?green?=?floor((i-1)*f),?blue?=?0,?alpha?=?255?}endreturn?imgendlocal?function?image_to_grey(img,?n)for?i=1,n?dolocal?y?=?floor(0.3*img[i].red?+?0.59*img[i].green?+?0.11*img[i].blue)img[i].red?=?y;?img[i].green?=?y;?img[i].blue?=?yendendlocal?N?=?400*400local?img?=?image_ramp_green(N)for?i=1,1000?doimage_to_grey(img,?N)end This?creates?a?table?with?160.000?pixels,?each?of?which?is?a?table?holding?four?number?values?in?the?range?of?0-255.?First?an?image?with?a?green?ramp?is?created?(1D?for?simplicity),?then?the?image?is?converted?to?greyscale?1000?times.?Yes,?that's?silly,?but?I?was?in?need?of?a?simple?example?... And?here's?the?FFI?version.?The?modified?parts?have?been?marked?in?bold:local?ffi?=?require("ffi")ffi.cdef[[typedef?struct?{?uint8_t?red,?green,?blue,?alpha;?}?rgba_pixel;]]local?function?image_ramp_green(n)local?img?=?ffi.new("rgba_pixel[?]",?n)local?f?=?255/(n-1)for?i=0,n-1?doimg[i].green?=?i*fimg[i].alpha?=?255endreturn?imgendlocal?function?image_to_grey(img,?n)for?i=0,n-1?dolocal?y?=?0.3*img[i].red?+?0.59*img[i].green?+?0.11*img[i].blueimg[i].red?=?y;?img[i].green?=?y;?img[i].blue?=?yendendlocal?N?=?400*400local?img?=?image_ramp_green(N)for?i=1,1000?doimage_to_grey(img,?N)end Ok,?so?that?wasn't?too?difficult: 1.First,?load?the?FFI?library?and?declare?the?low-level?data?type.?Here?we?choose?a?struct?which?holds?four?byte?fields,?one?for?each?component?of?a?4x8?bit?RGBA?pixel. 2.Creating?the?data?structure?with?ffi.new()?is?straightforward?—?the?'?'?is?a?placeholder?for?the?number?of?elements?of?a?variable-length?array. 3.C?arrays?are?zero-based,?so?the?indexes?have?to?run?from?0?to?n-1.?One?might?want?to?allocate?one?more?element?instead?to?simplify?converting?legacy?code. 4.Since?ffi.new()?zero-fills?the?array?by?default,?we?only?need?to?set?the?green?and?the?alpha?fields. 5.The?calls?to?math.floor()?can?be?omitted?here,?because?floating-point?numbers?are?already?truncated?towards?zero?when?converting?them?to?an?integer.?This?happens?implicitly?when?the?number?is?stored?in?the?fields?of?each?pixel. Now?let's?have?a?look?at?the?impact?of?the?changes:?first,?memory?consumption?for?the?image?is?down?from?22?Megabytes?to?640?Kilobytes?(400*400*4?bytes).?That's?a?factor?of?35x?less!?So,?yes,?tables?do?have?a?noticeable?overhead.?BTW:?The?original?program?would?consume?40?Megabytes?in?plain?Lua?(on?x64). Next,?performance:?the?pure?Lua?version?runs?in?9.57?seconds?(52.9?seconds?with?the?Lua?interpreter)?and?the?FFI?version?runs?in?0.48?seconds?on?my?machine?(YMMV).?That's?a?factor?of?20x?faster?(110x?faster?than?the?Lua?interpreter).轉(zhuǎn)載于:https://my.oschina.net/u/1449160/blog/199760
總結(jié)
以上是生活随笔為你收集整理的luajit日记-FFI库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MySQL ALTER语法
- 下一篇: Leetcode: Palindrome