Fedora 33
我正在尝试使用Raku从cupsGetDests2输出打印机列表。
这是C方式,尽管它也显示已删除的打印机:
#include <iostream>
#include <cups/cups.h>
int main() {
cups_dest_t* dests;
int nCount = cupsGetDests2(CUPS_HTTP_DEFAULT, &dests);
for (int i = 0; i < nCount; i++) {
cups_dest_t dest = dests[i];
std::cout << dest.name << std::endl;
}
}
$ list-printers
B4350
Cups-PDF
Cups_PDF_rn6 <-- deleted
Oki_B4350_on_dev_lp0_rn6 <-- deleted
Virtual_PDF_Printer
Virtual_PDF_Printer_rn6 <-- deleted
我添加了“
Raku邮件列表上的一个朋友给我看了这段代码:
#!/usr/bin/env raku
use NativeCall;
class CupsDest is repr('CStruct') {
has Str $.name; # This is the first field in the struct -- add more if you need them
}
sub cupsGetDests(Pointer is rw --> int32) is native('cups') {}
my $ptr = Pointer.new;
my $nCount = cupsGetDests($ptr);
for ^$nCount -> $i {
my $dest = nativecast(CupsDest, Pointer.new($ptr + $i *
nativesizeof(Pointer)));
say $dest.name;
}
但它在输出时出错:
$ ListPrinters.pl6
Cannot locate native library 'libcups.so': libcups.so: cannot open shared object file: No such file or directory
in method setup at /opt/rakudo-pkg/share/perl6/core/sources/947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 298
in block cupsGetDests at /opt/rakudo-pkg/share/perl6/core/sources/947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 587
libcups真的在那里!
$ locate libcups.so
/usr/lib/libcups.so.2
/usr/lib64/libcups.so.2
我做错了什么?
新信息:
我做了以下操作:
# cd /usr/lib
# ln -s libcups.so.2 libcups.so
# ls -al libcups*
-rwxr-xr-x. 1 root root 14612 Nov 10 06:07 libcupsimage.so.2
lrwxrwxrwx. 1 root root 12 Dec 6 01:03 libcups.so -> libcups.so.2
-rwxr-xr-x. 1 root root 710236 Nov 10 06:07 libcups.so.2
# cd /usr/lib64
# ln -s libcups.so.2 libcups.so
# ls -al libcups*
lrwxrwxrwx. 1 root root 23 Nov 23 22:09 libcupsfilters.so.1 -> libcupsfilters.so.1.0.0
-rwxr-xr-x. 1 root root 264440 Nov 23 22:09 libcupsfilters.so.1.0.0
-rwxr-xr-x. 1 root root 15256 Nov 10 06:08 libcupsimage.so.2
lrwxrwxrwx. 1 root root 12 Dec 6 01:04 libcups.so -> libcups.so.2
-rwxr-xr-x. 1 root root 686128 Nov 10 06:08 libcups.so.2
现在运行该程序可提供:
$ ListPrinters.pl6
B4350
(Str)
Segmentation fault (core dumped)
这是我的打印机列表:
$ lpstat -a
B4350 accepting requests since Thu 29 Oct 2020 01:36:30 PM PDT
Cups-PDF accepting requests since Tue 30 Apr 2019 04:05:39 PM PDT
Virtual_PDF_Printer accepting requests since Tue 29 Sep 2020 03:13:17 AM PDT
现在我做错了什么?
在Curt的帮助下解决了。我的新代码:
#!/usr/bin/env raku
use NativeCall;
class CupsDest is repr('CStruct') {
has Str $.name;
has Str $.instance;
has int32 $.is-default;
has int32 $.num-options;
has Pointer $.options;
}
sub cupsGetDests(Pointer is rw --> int32) is native('cups', v2) {}
my $ptr = Pointer.new;
my $nCount = cupsGetDests($ptr);
for ^$nCount -> $i {
my $dest = nativecast(CupsDest, Pointer.new($ptr + $i * nativesizeof(CupsDest)));
print "<" ~ $dest.name ~ ">\n";
}
输出:
$ ListPrinters.pl6
<B4350>
<Cups-PDF>
<Cups_PDF_rn6>
<Oki_B4350_on_dev_lp0_rn6>
<Virtual_PDF_Printer>
查看您正在调用的函数的定义,会出现以下情况
dests
可能比您在这里描述的结构更复杂。除了名称之外,它还包括一些其他字段,例如实例
。nativesizeof(CupsDest)
。您已经获得了指向普通的符号链接。因此,您也可以将
is native('cups')更改为is native('cups',v2),使其使用。所以2库。
@jjmerelo有一个正确的答案——我认为这是一个指针数组,但实际上它是一个结构数组。
填写整个结构:
class CupsDest is repr('CStruct') {
has Str $.name;
has Str $.instance;
has int32 $.is-default;
has int32 $.num-options;
has Pointer $.options;
}
并更改此行:
my $dest = nativecast(CupsDest, Pointer.new($ptr + $i * nativesizeof(CupsDest)));
(这是《Raku rebless不再处理继承类》的后续内容) 我试图想出一个更复杂的用例,但无法让代码正常工作。 这个想法是一个Person类,带有儿童和成人的混音子类。我们有一个UNICEF对象,当年龄超过18岁时将类型更改为Adult。 这一点显然是失败的,因为成年人是父母而不是孩子的混合体: 但它部分运行: 用一个类和一个混音来设置它是这样的: 但它不起作用: 我明白了。rebless系列指
我想写一个函数返回一个数组,其所有子数组的长度必须为2。例如,返回将是。 我定义: (1); 和 我觉得(1)太复杂了。有更简单的吗?
常见问题,Int Raku,如何合并,合并两个哈希? 说: 如何获取
使用以下代码: 结果: 而切换其他定义的注释块会导致: 坏的版本(有三个参数)是我想要的,有人能解释一下为什么它坏了吗?
我使用的是Windows10i7第四代笔记本电脑,内存为8GB。 我想找出从1到100000000的数字之和可以被5整除。 我正在尝试在Raku REPL中运行此代码: 代码运行了45分钟,仍然没有输出。我该如何克服呢? 在这种情况下,如何应用并发呢?我认为以上问题可以通过并发或任务并行来解决!!
在Perl中,使用Moo,可以围绕sub实现sub,它将围绕类中的其他方法。 如何在Raku中实现这种行为,最好使用角色?