【问题标题】:Array of structs as an attribute of a Perl 6 NativeCall struct结构数组作为 Perl 6 NativeCall 结构的属性
【发布时间】:2017-05-30 15:36:36
【问题描述】:

我正在尝试封装一个 C 结构,其中一个成员是指向结构的指针数组,但我在弄清楚如何去做时遇到了问题。

假设 C 代码如下所示:

struct foo
{
  unsigned char a;
};

struct bar
{
  struct foo *f[5];
};

这种代码有效:

use NativeCall;

class foo is repr('CStruct') {
  has uint8 $.a;
}

class bar is repr('CStruct') {
  has foo $.f1;
  has foo $.f2;
  has foo $.f3;
  has foo $.f4;
  has foo $.f5;
}

但这太可怕了。

CArray 在这里没有用,因为它只是一个指向数组的指针,而不是指针数组;我不能使用像has A @.a 这样的东西,因为repr('CStruct') 不能处理那种属性。

有什么提示吗?

【问题讨论】:

    标签: arrays raku nativecall


    【解决方案1】:

    我为此编写了一个示例代码。 C面:

    struct bar* create_bar_ptr(unsigned char a)
    {
        printf("GET A CHAR => %#0x = %c\n", a, a);
    
        struct bar* bar = (struct bar*)malloc(sizeof(struct bar));
    
        for (size_t i = 0;i < 5;i ++) {
            struct foo* tf = (struct foo*)malloc(sizeof(struct foo));
    
            tf->a = a + i;
            bar->f[i] = tf; 
        }
    
        printf("CREATE BAR PTR OK\n");
    
        return bar;
    }
    

    因为 Rakudo 不支持从 C 端获取堆栈变量,所以您应该使用 malloc 在堆上分配 struct bar

    然后用gcc编译代码,比如gcc -shared -fPIC -o libshasa.so xxx.c

    这是 Perl6 方面:

    use NativeCall;
    
    class foo is repr('CStruct') {
        has uint8 $.a;
    }
    
    class bar is repr('CStruct') {
        # Here you should use !!HAS!!, not has
        HAS Pointer[foo] $.f1;
        HAS Pointer[foo] $.f2;
        HAS Pointer[foo] $.f3;
        HAS Pointer[foo] $.f4;
        HAS Pointer[foo] $.f5;
    }
    
    
    sub create_bar_ptr(uint8) returns Pointer[bar] is native('./libshasa.so') { * }
    
    my Pointer[bar] $p = create_bar_ptr(uint8.new(97));
    
    say $p.deref."f{$_}"().deref.a for 1 .. 5;
    

    这个输出:

    GET A CHAR => 0x61 = a
    CREATE BAR PTR OK
    97
    98
    99
    100
    101
    

    【讨论】:

    • @FernandoSantagata 当然不支持,Rakudo 的数组与 C 数组有不同的内存布局(在堆栈上分配)。我想找到一种方法来做到这一点(使用元对象协议自动添加属性,模拟数组),但没有关于创建或手动操作角色或添加属性的文档(由 HAS 声明)以元对象协议的方式。也许您可以向 Rakudo 核心开发人员发送问题电子邮件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 2012-07-21
    • 2013-08-03
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    相关资源
    最近更新 更多