我正在尝试封装一个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')
不处理这种属性。
有什么提示吗?
发布于 2017-05-31 18:03:50
为此,我编写了一个示例代码。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 side:
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
https://stackoverflow.com/questions/44266457
复制相似问题