Raku NativeCall 到 LibX11 屏幕和显示

标签 raku nativecall

软呢帽 33

我正在尝试使用 Raku 的 NativeCall 与 libX11.so 对话以打印出我的屏幕和显示:

use NativeCall;

class Display is repr('CStruct') { has Pointer $.DisplayPtr };

# libX11.so --> X11
sub XOpenDisplay(Str $name = ':0') returns Display is native('X11') { * }
sub XDefaultScreen(Display $) returns int32 is native('X11') { * }

my Display $display = XOpenDisplay()
    or die "Can not open display";
 
my int $screen = XDefaultScreen($display);

print "display = <" ~ $display ~ ">\n";
print "screen =  <" ~ $screen  ~ ">\n";


$ libX11.pl6
display = <Display<90201160>>
screen =  <0>
问题。我遗漏了一些关于类语法的信息,因为它向我显示了一个指针地址而不是我的显示,我认为它是“:0”。另外我认为类声明应该在某处显示一个字符串。

最佳答案

您有点混淆了 Display(用于与 X 交互的对象)和显示名称(可用于识别和连接到 Display 的字符串)。
此外,对于 repr('CPointer') 最好使用 repr('CStruct') ,而不是 XDisplay * ,因为 Xlib 文档说它应该被视为一个不透明的指针,并且可以通过函数访问所有内容,并且将整个结构转换为 Raku 会很费力(而且不是很有用)。
由于它就像一个对象,因此您可以选择将所有 Xlib 函数封装在 Display 类中,并将它们包装在方法中,如 the pointers section of the NativeCall docs 所示。到目前为止,我对这种风格的代码的翻译是:

use NativeCall;

class Display is repr('CPointer') {
  sub XOpenDisplay(Str) returns Display is native('X11') { * }
  method new(Str $name = ':0') {
    XOpenDisplay($name);
  }

  # You can wrap a libX11 function in a method explicitly, like this...
  sub XDisplayString(Display) returns Str is native('X11') { * }
  method DisplayString {
    XDisplayString(self);
  }

  # Or implicitly, by putting 'is native' on a method declaration 
  # and using 'is symbol' to match the names
  # (self will be passed as the first argument to the libX11 function)
  method DefaultScreen() returns int32 is native('X11') 
    is symbol('XDefaultScreen') { * }

  method Str {
    "Display({ self.DisplayString })";
  }
}

my Display $display .= new
    or die "Can not open display";

my int $screen = $display.DefaultScreen;

print "display = <" ~ $display ~ ">\n";
print "screen =  <" ~ $screen  ~ ">\n";
我为 method Str 提供了一个 Display ,以便它可以直接打印,但同样,不要将对象与用来获取一个的字符串混淆。从这里开始,您可以向 Display 中添加更多方法,并以相同的方式定义 ScreenWindow 等。您不必这样做——您可以自由地公开定义 subs 并使用对 XOpenDisplay 和其他所有内容的调用,就像您在编写 C 一样,但 OO 风格往往更简洁一些。这是你的选择。

关于Raku NativeCall 到 LibX11 屏幕和显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65388341/

相关文章:

casting - Perl 6 nativecast() 到具有 repr ('CPointer' ) 的对象时 GC 会破坏吗?

raku - 使用 NativeCall 将 CStruct 中的内联 CArray 传递给共享库

raku - 在 Perl 6 中,如何使用 NativeCall 接口(interface)将原始字节转换为浮点?

blocking - ncurses:为什么 getch 不等到我按下一个键?

raku - 如何将 LEAVE 移相器导出到 use 语句的外部范围

redis - 请求输出时 Perl6 Redis 卡住了

raku - 如何在 Raku 中删除多方法

raku - 在Perl6中声明多个范围的数组

multithreading - 在 Perl 6 中运行自馈 channel

Raku/Perl6 : how do you code a NULL with NativeCall