В основном вам нужно только скопировать все объявления из заголовков в раздел ffi.cdef
, а затем вызвать эти имена через дескриптор библиотеки.В принципе, вы можете переводить код C один на один, за исключением того, что берете адрес переменной.Тем не менее, это задокументировано в учебнике FFI, на который вы ссылаетесь (http://luajit.org/ext_ffi_tutorial.html#idioms)
C code Lua code
Functions with outargs int len = x; local len = ffi.new("int[1]", x)
void foo(int *inoutlen); foo(&len); foo(len)
y = len; y = len[0]
. Вот ваш код на C в LuaJIT. Я не копировал определения для Display
и XImage
, потому что мы никогдаполучить доступ к своим членам и использовать только указатели на них, поэтому они остаются непрозрачными struct
s.
local ffi = assert(require("ffi"))
ffi.cdef[[
// Types from various headers
typedef struct _Display Display;
typedef struct _XImage XImage;
typedef struct {
unsigned long pixel;
unsigned short red, green, blue;
char flags; /* do_red, do_green, do_blue */
char pad;
} XColor; // Xlib.h
typedef unsigned long XID; // Xdefs.h
typedef XID Window; // X.h
typedef XID Drawable; // X.h
typedef XID Colormap; // X.h
// Functions from Xlib.h
Display *XOpenDisplay(
char* /* display_name */
);
int XDefaultScreen(
Display* /* display */
);
Window XRootWindow(
Display* /* display */,
int /* screen_number */
);
XImage *XGetImage(
Display* /* display */,
Drawable /* d */,
int /* x */,
int /* y */,
unsigned int /* width */,
unsigned int /* height */,
unsigned long /* plane_mask */,
int /* format */
);
int XFree(
void* /* data */
);
int XQueryColor(
Display* /* display */,
Colormap /* colormap */,
XColor* /* def_in_out */
);
Colormap XDefaultColormap(
Display* /* display */,
int /* screen_number */
);
// Functions from Xutil.h
unsigned long XGetPixel(
XImage *ximage,
int x, int y);
]]
local X11 = assert(ffi.load("X11"))
local AllPlanes = -1 -- Xlib.h: #define AllPlanes ((unsigned long)~0L)
local XYPixmap = 1 -- X.h: #define XYPixmap 1
local c = ffi.new("XColor[1]")
local d = X11.XOpenDisplay(ffi.NULL)
local x = 1920 / 2
local y = 1080 / 2
local image = X11.XGetImage(d, X11.XRootWindow(d, X11.XDefaultScreen(d)), x, y, 1, 1, AllPlanes, XYPixmap)
c[0].pixel = X11.XGetPixel(image, 0, 0)
X11.XFree(image)
X11.XQueryColor(d, X11.XDefaultColormap(d, X11.XDefaultScreen(d)), c)
print(string.format("%d %d %d", c[0].red/256, c[0].green/256, c[0].blue/256))