我Buf
想传递给C库中有一个内存块,但是该库将在单个调用的生命周期之外使用内存。
我知道这是有问题的,因为垃圾收集器可以移动内存。
为了传递a Str
,Nativecall文档
说:“如果C函数要求字符串的生存期超过函数调用的长度,则必须对参数进行手动编码并以CArray [uint8]的形式传递”,并举例说明:
my $array = CArray[uint8].new($string.encode.list);
Run Code Online (Sandbox Code Playgroud)
我的问题是:我是否必须为同一件事做同样的事情Buf
?万一它被GC移动了?还是GC会离开我的Buf
位置?对于短字符串,这没什么大不了的,但是对于大内存缓冲区,这可能是昂贵的操作。(例如,请参见Archive :: Libarchive,可以将其Buf
与tar文件一起传递。该代码有问题吗?
multi method open(Buf $data!) {
my $res = archive_read_open_memory $!archive, $data, $data.bytes;
...
Run Code Online (Sandbox Code Playgroud)
是否有(可能有呢?应该有?)某种trait
上Buf
,它告诉GC不能移动它?我知道如果我向中添加更多数据可能会很麻烦Buf
,但我保证不会这样做。对于一个Blob
不变的东西呢?
至少在目前,您将在MoarVM上避免使用此方法,只要您在本机代码中需要对Blob
or或Buf
alive 的引用一直保持下去,并且(在情况下Buf
)您不需要对其进行写操作可能会导致调整大小。
MoarVM 在苗圃中分配Blob
/ Buf
对象,并将在GC运行期间将其移动。但是,该对象不保存数据。而是保留大小和指向存储值的内存块的指针。该内存块未使用GC分配,因此不会移动。
+------------------------+
| GC-managed Blob object |
+------------------------+ +------------------------+
| Elements |----->| Non-GC-managed memory |
+------------------------+ | (this bit is passed to |
| Size | | native code) |
+------------------------+ +------------------------+
Run Code Online (Sandbox Code Playgroud)
是否应该依靠这个是一个棘手的问题。一些注意事项:
“为其添加特征”的问题在于,至少在JVM上,该决定似乎需要在分配保存数据的内存时预先做出。在这种情况下,便携式解决方案可能无法将现有的Buf
/ Blob
标记为此类。也许一种更好的方法是要求I / O类的东西提供类似的东西CArray
,以便通过首先将数据放在“正确的内存”中来实现零复制。这可能是一个合理的功能要求。
归档时间: |
|
查看次数: |
110 次 |
最近记录: |