raku - nativecast() 是否创建一个新容器?

标签 raku nativecall

我正在编写一个 C 库的接口(interface)。一个 C 函数分配一些内存,读取一个值,然后返回一个 void *指向该缓冲区的指针,随后将被释放。
我希望确定当我将调用的输出分配给 nativecast(Str, $data) 时对于 Raku Str 变量,数据被分配给变量(复制到),而不仅仅是绑定(bind)到它,所以我可以在分配后不久释放 C 函数分配的空间。
这大概是代码的样子:

my Pointer $data = c_read($source);
my Str $value = nativecast(Str, $data);
c_free($data);
# $value is now ready to be used
我通过 valgrind 运行此代码,它没有报告任何引用已释放内存缓冲区的尝试。我还是很好奇。

最佳答案

Str 的内部结构与 C 字符串完全不兼容。因此,它们必须在使用之前进行解码。
更具体地说,如果 MoarVM 还没有 NFC 代码点,则 MoarVM 将字素簇存储为 [负] 合成代码点。这意味着即使是同一个程序的两个实例也可能对同一个字素簇使用不同的合成代码点。
即使忽略这一点,MoarVM 也将字符串存储为不可变的数据结构。这意味着它不能只使用 C 字符串,因为 C 代码可能会在 MoarVM 下改变它,从而打破该假设。
我敢肯定还有很多原因导致它不能按原样使用 C 字符串。

就像我说的,Str 的内部结构与 C 字符串完全不兼容。因此,它继续使用 C 函数分配的空间的可能性为零。
这里最大的问题是调用 nativecast释放缓冲区后。

关于raku - nativecast() 是否创建一个新容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67147060/

相关文章:

raku - 如何打印对象,输入 nqp

macros - 宏定义中的"Too few positionals"

raku - 每当signal()以react block 顺序依赖时?

raku - Perl 6 中交替出现的文字正则表达式中的重复元素

raku - 有没有办法从 Perl6 模块代码中的 META6.json 获取版本?

使用 fcntl 从 stdout 创建新文件描述符在文件中失败

raku - 将函数指针放入 Perl6 NativeCall CStruct

raku - 通过 NativeCall 在 Raku 中使用 void 结构

docker - 在 Raku 中通过 NativeCall 调用 GSL 函数会引发错误