gpt4 book ai didi

raku - 如何将 CArray[ of-struct] 从 Raku 传递给 C?

转载 作者:行者123 更新时间:2023-12-03 15:46:53 25 4
gpt4 key购买 nike

我如何使这项工作?
更新:在搜索包括 Raku 规范测试在内的 Github 之后,我还没有找到任何传递 CArray[of-structs] 的示例。 Here there is a post by Christoph从 2017 年开始,它提供了“解决方法”。
Christoph 的解决方案可能有效,但如果没有更好的方法,在 NativeCall 中会更好。
在 Github 上有 a Rakudo test that uses a int TakeAStructArray(Struct **structs) ,如果您可以编写一个 C 函数来重新打包其参数以转发到 TakeAnArrayOfStruct( struct Struct[]),这可能会有所帮助。 .
下面,JJMerelo 秒我怀疑由于 Rakudo 中的错误而失败。
我有一个 C 使用类似于所使用的 timespec 结构的函数
在 NativeCall 文档中:
结构体{
int show2(struct TS ts[2]){
printf( "show2: (1) %ld %ld (2) %ld %ld\n",
ts[0].ot, ts[0].one, ts[1].ot, ts[1].one);
返回0;
}
调用时工作正常C .
从 Raku (moar) 调用不起作用:

class TS is repr('CStruct') {
has long $.ot;
has long $.one;
}

sub show2( CArray[TS] --> int32) is native(
'/home/rir/Raku/try-CArray/libshow.so'
) {*}

my $A = CArray[TS].new;
$A[1] = TS.new( :ot(50), :one(60));
$A[0] = TS.new( :ot(30), :one(40));
show2( $A);
say " s/b 30 40 50 60\n";
没有错误,只是结果如下:
show2: (1)  94658691693328 94658695469968  (2) 0 0
s/b 30 40 50 60
类比函数 int show2long( long i[2] )int showTS(int show1( struct TS *ts )工作。

最佳答案

不久前我遇到了这个确切的问题,这迫使我写 a workaround
简短的回答,这在 NativeCall 中尚不支持。
长答案:如上所述,有一个解决方法。如果你不想浏览我的代码,答案归结为:
使用 Pointer .
或者,更好的是,一个 Buf 然后使用 NativeCall::Blob 的 pointer-to .
然后,您将使用以下例程将元素作为位置访问:

  # Cribbed from MySQL::Native. Thanks, ctilmes!
method AT-POS(Int $field) {
nativecast(
T,
Pointer.new( $!b + $field * nativesizeof(T) )
)
}
以及在适当的索引处分配结构的以下方法
  method bind (Int() $pos, T $elem) {
my uint64 $p = $pos;

memcpy(
Pointer.new( $!b + $p * nativesizeof(T) ),
nativecast(Pointer, $elem),
nativesizeof(T)
);
}
因此,这种事情的基本实现将是:
use NativeHelper::Blob;

class TypedBuffer {
has Buf $!b;

submethod BUILD ( :@array-of-structs ) {
# Assumes that array contains homogeneous struct values!
$!b = Buf.allocate(
@array-of-structs.elems * nativesizeof( @a[0].WHAT )
)
}

method new (@array-of-structs) {
self.bless( :@array-of-structs);
}

method bind (Int() $pos, T $elem) {
my uint64 $p = $pos;

memcpy(
Pointer.new( $!b + $p * nativesizeof(T) ),
nativecast(Pointer, $elem),
nativesizeof(T)
);
}

method AT-POS(Int $field) {
nativecast(
T,
Pointer.new( $!b + $field * nativesizeof(T) )
)
}

method Pointer {
pointer-to($!b);
}

}
基本用法是:
my $aos = TypedBuffer.new(@array-of-structs);  # Init
my $struct = $aos[0]; # Retrieve first element
$aos.bind(2, $new-struct); # Replace third element
my-c-func($aos.Pointer); # Make call to a C Function

关于raku - 如何将 CArray[ of-struct] 从 Raku 传递给 C?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64684291/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com