c - 如何为luajit的ffi实现X11(返回屏幕像素的颜色)C代码?
问题描述
我想用 luajit 记录我屏幕的一小部分。
还没有找到任何模块。除了http://luajit.org/ext_ffi.html之外,几乎没有任何关于 luajit 的 ffi 的文档/教程/示例,它没有提供任何使用其他 C 库的示例。
我有一个原生的 C 代码片段。你将如何实现 luajit 的 ffi 的 C 代码?
Luajit 示例代码:
--ffi part
local screen = {}
for y = 1, 100 do
for x = 1, 100 do
local r, g, b = ffi.C.getpixel(x, y)
table.insert(screen, r)
end
end
C 代码片段:
#include <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
int main()
{
XColor c;
Display *d = XOpenDisplay((char *) NULL);
int x=1920/2; // Pixel x
int y=1080/2; // Pixel y
XImage *image;
image = XGetImage (d, XRootWindow (d, XDefaultScreen (d)), x, y, 1, 1, AllPlanes, XYPixmap);
c.pixel = XGetPixel (image, 0, 0);
XFree (image);
XQueryColor (d, XDefaultColormap(d, XDefaultScreen (d)), &c);
printf("%d %d %d\n", c.red/256, c.green/256, c.blue/256);
return 0;
}
解决方案
基本上,您只需将所有声明从标题复制到该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]
这是你在 LuaJIT 中的 C 代码。我没有复制 and 的定义Display
,XImage
因为我们从不访问它们的成员,只使用指向它们的指针,所以它们仍然是 opaque struct
。
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))
推荐阅读
- parsing - yacc:冲突:1 减少/减少
- angular - Angular - 在哪里放置 firebase 的脚本调用
- python - 我在这个脚本中使用 if / then 有什么问题?
- php - PHP while循环使用TCPDF输出多个单个PDF
- scala - scala对象伴侣和特征的问题
- agda - 无法解析左侧 (m + 1) * n
- javascript - 带有 TypeScript 的 Vue.js 从 Twig 错误属性获取数据不存在
- elasticsearch - Elasticsearch - at&t 和 procter&gamble 案例
- scala - 如何使用 net.ruippeixotog.scalascraper 从 html 表中抓取所有链接
- javascript - 包含日期的变量更改值而不被更改