Luajit笔记(2)——FFI库(1)

Luajit提供的FFI库(ffi.*)允许Lua代码调用外部的C函数和使用C数据结构。但是默认情况下,FFI库不会被加载和初始化。因此建议在每个使用FFI库的Lua文件开头加载:

local ffi = require("ffi")

看下面这个例子:

local ffi = require("ffi")

ffi.cdef[[
int printf(const char *format, ...);
]]

ffi.C.printf("Hello world!\n")

执行结果如下:

Hello world!

(1)
ffi.cdef的定义如下:

ffi.cdef(def)

def必须是一个Lua字符串,建议使用“[[...]]”这种格式。ffi.cdef包含的是对C语言类型的定义和外部符号(变量和函数)的声明(仅仅是声明,并没有和实际的内存地址进行绑定,实际的绑定是通过C library namespace)。要注意对C类型的声明不会经过C预处理器,除了#pragma pack以外,包括#define在内的指令都要进行处理替换,比如使用enum等等。

(2)
ffi.C是默认的C library namespace。它同编译器有些类似,但不用显示地声明链接库。在POSIX系统上,ffi.C会在defaultglobalnamespace上绑定符号。包括libclibm,等等。还有Luajit自身提供的API

 

Luajit笔记(1)——Luajit简介

Luajit(官方网站:http://luajit.org/)是针对Lua语言的一个JIT(Just-In-Time)的编译器,目前完全支持Lua5.1版本。

下载Luajit源代码后,编译安装很简单:

make
make install

生成一个可执行文件:luajit(其实是一个符号连接):

[root@Fedora lua_program]# ls -lt /usr/local/bin/luajit
lrwxrwxrwx. 1 root root 12 Jul 27 21:06 /usr/local/bin/luajit -> luajit-2.0.4

luajit可以用来运行Lua脚本和语句:

[root@Fedora lua_program]# luajit
LuaJIT 2.0.4 -- Copyright (C) 2005-2015 Mike Pall. http://luajit.org/
JIT: ON CMOV SSE2 SSE3 fold cse dce fwd dse narrow loop abc sink fuse
> print("Hello world\n")
Hello world

此外还会生成一些动态和静态链接库,供应用程序使用:

lrwxrwxrwx.  1 root root      22 Jul 27 21:06 libluajit-5.1.so -> libluajit-5.1.so.2.0.4
lrwxrwxrwx.  1 root root      22 Jul 27 21:06 libluajit-5.1.so.2 -> libluajit-5.1.so.2.0.4
-rwxr-xr-x.  1 root root  458144 Jul 27 21:06 libluajit-5.1.so.2.0.4
-rw-r--r--.  1 root root  790748 Jul 27 21:06 libluajit-5.1.a

以下面的C程序为例:

#include <stdio.h>
#include <string.h>
#include "luajit-2.0/lua.h"
#include "luajit-2.0/lualib.h"
#include "luajit-2.0/lauxlib.h"


int main (void) {
    char buff[256];
    int error;
    lua_State *L = lua_open();   /* opens Lua */
    luaL_openlibs(L);

    while (fgets(buff, sizeof(buff), stdin) != NULL) {
        error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
                lua_pcall(L, 0, 0, 0);
        if (error) {
          fprintf(stderr, "%s", lua_tostring(L, -1));
          lua_pop(L, 1);  /* pop error message from the stack */
        }
    }

    lua_close(L);
    return 0;
}

编译(链接Luajit库):

gcc -g -o a a.c -lluajit-5.1

运行:

[root@Fedora test]# ./a
print("hello")
hello