luajit FFI简单使用(1)

luajit利用ffi结合C语言实现面向对象的封装库 luajit中,利用ffi可以嵌入C,目前luajit的最新版是2.0.4,在这之前的版本我还不清楚这个扩展库具体怎么样,不过在2.04中,真的很爽。  既然是嵌入C代码,那么要说让lua支持面向对象,不如说是让C语言模拟面向对象编程,然后让luajitffi嵌入。要文字彻底来描述清楚这个问题,我的表达能力很有限,说不清楚,所以直接用代码来说吧。//C++ class foo_type{ p 阅读详情

本文参考了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 { uint8_t x, y; } position;
int dot_produce(position *a, position *b);
int dot_produce(position *a, position *b) {
    int ret = (a->x) * (b->x) + (a->y * b->y);
    return ret;
}

lua中调用


local ffi = require("ffi")
ffi.cdef[[
typedef struct { uint8_t x, y; } 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]))

进阶

调用zlib库

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])
end

local 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

-- Simple 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做转换时使用。

为c类型绑定上元表

local ffi = require("ffi")
ffi.cdef[[
typedef struct { double x, y; } point_t;
]]

local point
local mt = {
  __add = function(a, b) return point(a.x+b.x, a.y+b.y) end,
  __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
  __index = {
    area = function(a) return a.x*a.x + a.y*a.y end,
  },
}
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库,想做成面向对象就能通过这个调配一下就好了。
在官网中的解释

The C type metamethod mechanism is most useful when used in conjunction with C libraries that are written in an object-oriented style.
四、FFI和第三方模块 目录 FFI 如何调用外部C库函数? Openresty自带很多luaJIT库 第三方模块 FFI FFI 库,是 LuaJIT 中最重要的一个扩展库。它允许从纯 Lua 代码调用外部 C 函数,使用 C 数据结构。有了它,就不用再像 Lua 标准math库一样,编写 Lua 扩展库。把开发者从开发 Lua 扩展 C 库(语言/功能绑定库)的繁重工作中释放出来。学习完本小节对... 阅读详情

相关推荐

OpenResty从入门到精通08-LuaJIT分支和标准Lua有什么不同?

让我们来回顾下今天的内容。OpenResty 出于性能的考虑,选择了 LuaJIT 而不是标准 Lua,并且维护了自己的 LuaJIT 分支。而 LuaJIT 基于 Lua 5.1 的语法,并选择性地兼容了部分 Lua5.2 和 Lua5.3 的语法,形成了自己的体系。至于你需要掌握的Lua 语法,在下标、字符串拼接、数据结构和变量上,都有自己鲜明的特点,在写代码的时候你应该特别留意。你在学习 LuaLuaJIT 的时候,是否遇到一些陷阱和坑呢?

fegus的博客 962

LuaJIT & FFI】优雅的与C交互

LuaJITFFI是两个非常强大的工具,它们可以帮助开发人员在Lua中实现高性能的代码。

Cauchy的博客 3314

luajit集成篇/平台相关篇 | 合理用好lua+unity,更省性能的方案整理

luajit集成篇 大家都知道luajit比原生lua快,快在jit这三个字上。 但实际情况是,luajit的行为十分复杂。尤其jit并不是一个简单的把代码翻译成机器码的机制,背后有很多会影响性能的因素存在。

m0_58523831的博客 1万+

lua ffi.string

缘起使用ffilua包一个rsa算法, 刚刚学习ffi,连文档都没仔细看过,当返回加密结果时,如果直接返回CDATA,则解密没有问题,如果转为lua string(使用ffi.string) ,则后续无法解密调试直接在lua中调试基本无法凑效重新编译openssl的libcrypt库,加入调试信息,先是祭出gdb,调的晕乎乎的;然后,则可以地方修改C代码,打印调试信息发现,使用ffi.strin...

章志强的专栏 4693

LuaJIT入门教程:5分钟快速搭建高性能Lua开发环境

想要体验**高性能Lua编程**的魅力吗?LuaJIT作为Lua语言的即时编译器,能够将Lua代码的运行速度提升数倍,是游戏开发、嵌入式系统和脚本优化的终极选择。本教程将带你用5分钟时间完成LuaJIT开发环境的完整搭建。 ## 什么是LuaJITLuaJIT是一个高性能的Lua解释器和即时编译器,它完全兼容标准的Lua 5.1语言规范。与标准Lua相比,LuaJIT通过先进的JIT编译技

gitblog_00537的博客 748

推荐使用LuaJIT 2.1 - 高性能的Lua JIT编译器

LuaJIT 2.1 是一款由Mike Pall开发的高效能的Just-In-Time(JIT)编译器,专为动态脚本语言Lua设计。作为开源软件,它遵循MIT许可,允许自由使用和分发。该项目的主页位于[https://luajit.org/](https://luajit.org/),在这里你可以找到详细的文档和最新信息。 ## 项目技术分析 LuaJIT 的核心优势在于其优化的JIT编译引擎...

gitblog_00077的博客 954

3.luajit简介

--------------------- luajit环境 openresty使用的解释器不是官方的lua解释器,而是第三方的luajit,为的是追求极致的性能 luajit=汇编编写的解释器+jit编译器 基于lua5.1 goto for i=1,10 do if i%2==0 then goto continue end print("i=",i) ::cont...

Salted fish in hand, I have the world. 390

终极Lua性能加速方案:LuaJIT 2.1完整指南

LuaJIT 2.1是一款革命性的高性能即时编译器,专为动态脚本语言Lua设计。作为OpenResty团队维护的分支版本,它提供了比标准Lua解释器高出数倍的执行速度,同时保持完全兼容Lua 5.1语法。无论您是游戏开发者、Web后端工程师还是嵌入式系统程序员,LuaJIT都能为您的项目带来显著的性能提升。 ## 为什么选择LuaJIT作为您的首选脚本引擎 LuaJIT的核心优势在于其先进的即

gitblog_00069的博客 790

LuaJIT 2.1终极指南:如何让Lua脚本运行速度提升10倍以上

你是否在为Lua脚本的性能瓶颈而烦恼?想要让游戏逻辑、Web服务器或嵌入式系统的运行速度获得质的飞跃?LuaJIT 2.1就是你的解决方案!作为OpenResty分支的LuaJIT实现,这款高性能即时编译器能够将Lua代码的执行速度提升5-10倍,让脚本语言也能拥有接近原生代码的性能表现。 ## 🚀 为什么选择LuaJIT而不是标准Lua? 传统的Lua解释器虽然灵活易用,但在性能要求高的场

gitblog_00562的博客 860

LuaJIT 2.1终极指南:高性能脚本引擎的完整解析与实战

LuaJIT 2.1是一款基于OpenResty分支的高性能Just-In-Time编译器,专为Lua语言优化设计。该项目在保持Lua语言简洁特性的同时,通过先进的即时编译技术将脚本代码转换为高效的机器码,为开发者提供接近原生C语言的执行性能。作为开源项目,它遵循MIT许可证,支持自由使用和二次开发。 ## 核心技术架构深度剖析 ### JIT编译引擎工作原理 LuaJIT的核心技术在于其独特

gitblog_01200的博客 964

OpenResty/luajit2完全指南:从入门到精通的高性能Lua JIT编译器

OpenResty/luajit2是一款高性能的Lua JIT编译器,它在标准Lua的基础上提供了即时编译功能,能够显著提升Lua代码的执行速度。本指南将带你全面了解这款强大工具的安装、配置、核心功能及性能优化技巧,帮助你快速掌握并充分发挥其高性能特性。 ## 一、什么是OpenResty/luajit2? LuaJIT是一款即时编译(JIT)的Lua引擎,它不仅完全向上兼容Lua 5.1,还

gitblog_00230的博客 864

luajit开发文档中文版(二)LuaJIT扩展

2022年6月10日15:33:04 luajit开发文档中文版()下载和安装 luajit开发文档中文版()LuaJIT扩展 luajit开发文档中文版()FAQ 常见问题 luajit开发文档wiki中文版() 总目录 luajit开发文档wiki中文版() LuaJIT 扩展 luajit开发文档wiki中文版()性能调优和测试 luajit开发文档wiki中文版() ...

Z.X的博客 1730

python不同方法_不同方式的python实现,它们之间的差异是什么?

不同方式的python实现,它们之间的差异你们知道吗?python从2017年开始就一直受到关注与追捧,它与高新科技人工智能相联系,但对于什么是python?python能干什么?似乎是最为热门的话题。这里我先解释下:什么是python:其实python就是是一种面向对象的解释型计算机程序设计语言,具有丰富和强大的库,语言因其简洁性、易读性以及可扩展性受到欢迎。python能干什么:python可...

weixin_39900736的博客 292

luaffi - 用于Lua的动态类型系统增强库

luaffi - 用于Lua的动态类型系统增强库 是一个用于 Lua 的开源库,它提供了对 Lua 动态类型的增强功能,包括生成元表、检查类型、创建新的类型等。这个库的目标是提高 Lua 程序的灵活性和可读性。 能做什么? 利用 luaffi 库,你可以实现以下功能: 自定义类型:luaffi 允许你创建自己的类型,并为这些类型定义方法和属性。 类型检查:通过 luaffi,你可以方便地检查变量...

gitblog_00001的博客 960

FFI和第三方模块

一、FFI FFILuaJIT中的一个扩展库,它允许我们使用 Lua 代码调用C语言的数据结构和函数。 FFI库在很大程度上避免了在C中编写繁琐的手动Lua/C绑定的需要。无需学习单独的绑定语言 - 它解析普通的C声明!这些可以从C头文件或参考手册中剪切粘贴。 如何调用外部C库函数呢? 1、加载FFI库。 2、为函数添加C声明。 3、调用命名的C函数。 看一个官方提供的简单示例:...

INGNIGHT的专栏 1095

Lua FFI 实战

May 19, 2013 由来 FFI库,是LuaJIT中最重要的一个扩展库。它允许从纯Lua代码调用外部C函数,使用C数据结构。有了它,就不用再像Lua标准math库一样,编写Lua扩展库。把开发者从开发Lua扩展C库(语言/功能绑定库)的繁重工作中释放出来。 FFI简介 FFI库,允许从纯Lua代码调用外部C函数,使用C数据结构。 FFI库最大限度的省去了使用C手

把握自己。 1万+

LuaJIT 学习(4)—— FFI 语义

FFI 语义

alenliu's blog 1514

luajit ffi 小结

Luajit ffi 接口使用小结: 1. 使用 Luajit ffi 加载 C 链接库 2. 使用 Luajit ffi 调用 C 函数 3. 使用 Luajit ffi 处理基本类型对象,结构体对象,字符串对象 cdata 4. cdata 赋值及修改 本文仅限于使用 C 链接库,后面文章将介绍使用 Luajit ffi 加载 C++ 链接库

AlexWoo0501的博客 1万+
上一篇: cmake套路介绍
下一篇: 使用python内建asyncore编写socket client
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值