【发布时间】:2017-09-29 03:08:16
【问题描述】:
我有一个第三方 C 库,它定义了一个类似的结构:
struct myStruct {
int a;
int b;
char str1[32];
char str2[32];
};
还有一个函数,它接受一个指向这个结构的指针并填充它。我需要我的 Perl6 本机调用来提供该结构,然后读取结果。
到目前为止,我在 Perl6 中将结构定义为:
class myStruct is repr('CStruct') {
has int32 $.a;
has int32 $.b;
has Str $.str1; # Option A: This won't work as Perl won't know what length to allocate
has CArray[uint8] $.str2; # Option B: This makes more sense, but again how to define length?
# Also, would this allocate the array in place, or
# reference an array that is separately allocated (and therefore not valid)?
}
还有一个像这样的原生调用:
sub fillStruct(myStruct) is native('test_lib') { ... }
我的 $struct = myStruct.new();
填充结构($结构); # 到目前为止我尝试过的任何变体都会出现 seg 错误
我怎样才能做到这一点?
【问题讨论】:
-
您尝试过文档中的代码吗? docs.perl6.org/language/nativecall#Structs 我们可以推断结构将动态调整大小,同时考虑到
CArray的当前大小。文档演示了更改TWEAK()中的元素。所以尝试传递一个完整的数组而不是一个空的数组。 (如果你想让它为空,请填写0。) -
但是 perl 在技术上不需要计算大小。它只需要可用的内存。所以填充数组应该可以解决问题。 (如果我记得我的 C++ 时代,结构并不总是相同的大小,因为您可以将可变长度缓冲区作为最后一个元素。)
-
C/C++ 结构总是以固定大小定义,尽管它们可以映射/转换到更大的内存区域,并且可以通过指针操作访问。
-
我也尝试了推荐的 TWEAK 函数方法,将每个 uint8 数组显式初始化为正确的大小,但是当我运行它时仍然出现 seg 错误。我怀疑 Perl 是将指向字符串数组的指针插入到结构中,而不是根据需要直接在结构中定义数组。
-
遗憾的是,rakudo 仍然缺少您需要的功能;您可以从 nativehelpers 模块中得到一些缓解:modules.perl6.org/search/?q=nativehelpers - 希望对您有所帮助
标签: raku nativecall