首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >作为Perl 6 NativeCall结构属性的结构数组

作为Perl 6 NativeCall结构属性的结构数组
EN

Stack Overflow用户
提问于 2017-05-30 23:36:36
回答 1查看 198关注 0票数 9

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

假设C代码看起来像这样:

代码语言:javascript
运行
复制
struct foo
{
  unsigned char a;
};

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

这类代码可以工作:

代码语言:javascript
运行
复制
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')不处理这种属性。

有什么提示吗?

EN

回答 1

Stack Overflow用户

发布于 2017-05-31 18:03:50

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

代码语言:javascript
运行
复制
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 side:

代码语言:javascript
运行
复制
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;

这将输出以下内容:

代码语言:javascript
运行
复制
GET A CHAR => 0x61 = a
CREATE BAR PTR OK
97
98
99
100
101
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44266457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档