Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种方法可以强制在从特定堆栈帧返回后不使用Rust原始指针? 我为一个(主要是C风格)C++插件SDK编写了一个Rug包装器。插件主机是一个运行事件循环的图形桌面应用程序。插件作为事件循环的一部分定期被调用。无论何时发生这种情况,插件都可以控制并调用任意主机函数_Rust_Ffi_Lifetime - Fatal编程技术网

有没有一种方法可以强制在从特定堆栈帧返回后不使用Rust原始指针? 我为一个(主要是C风格)C++插件SDK编写了一个Rug包装器。插件主机是一个运行事件循环的图形桌面应用程序。插件作为事件循环的一部分定期被调用。无论何时发生这种情况,插件都可以控制并调用任意主机函数

有没有一种方法可以强制在从特定堆栈帧返回后不使用Rust原始指针? 我为一个(主要是C风格)C++插件SDK编写了一个Rug包装器。插件主机是一个运行事件循环的图形桌面应用程序。插件作为事件循环的一部分定期被调用。无论何时发生这种情况,插件都可以控制并调用任意主机函数,rust,ffi,lifetime,Rust,Ffi,Lifetime,我想包装的一个C函数返回一个原始指针。函数返回后,指针保证是有效的C字符串,因此可以安全地取消对它的引用。但是,在插件回调返回(从而将控制权返还给主机)之后,指针可能会过时。我如何为此编写一个符合人体工程学的函数包装器,它在某个点上不会导致未定义的行为,例如,当消费者尝试在下一个事件循环中访问字符串时 我考虑过以下方法: 1.返回一个拥有的字符串 我可以立即取消对指针的引用,并将内容复制到拥有的CString: pub fn从\u host()获取\u字符串\u->CString{ 让ptr:*

我想包装的一个C函数返回一个原始指针。函数返回后,指针保证是有效的C字符串,因此可以安全地取消对它的引用。但是,在插件回调返回(从而将控制权返还给主机)之后,指针可能会过时。我如何为此编写一个符合人体工程学的函数包装器,它在某个点上不会导致未定义的行为,例如,当消费者尝试在下一个事件循环中访问字符串时

我考虑过以下方法:

1.返回一个拥有的字符串 我可以立即取消对指针的引用,并将内容复制到拥有的
CString

pub fn从\u host()获取\u字符串\u->CString{
让ptr:*const c_char=unsafe{ffi.get_string()};
不安全{CStr::from_ptr(ptr).to_owned()}
}
这是自以为是的——也许我的包装器的使用者对获得一个自己的字符串不感兴趣,因为他们只是想进行比较(这甚至是我要说的主要用例)。复制字符串将是一种完全的浪费

2.返回原始指针
pub fn从\u host()获取\u字符串\u->*常量c\u char{
不安全{ffi.get_string()}
}
这就把问题转移到了消费者身上

3.返回一个
CStr
参考(不安全方法)
pub不安全fn从主机T获取字符串)->T{
让ptr:*const c_char=unsafe{ffi.get_string()};
f(不安全{CStr::from_ptr(ptr)})
}
pub fn消费函数(){
设length=with_string_from_host(|s|s.to_bytes().len());
}
这很管用,但确实需要习惯


这些解决方案都不是真正令人满意的

有没有办法确保返回值被“立即”使用,这意味着它不会存储在任何地方,也不会逃出调用方的范围

这听起来像是引用/生命周期的工作,但我不知道有任何生命周期注释表示“仅在当前stackframe中有效”。如果有,我会用它(只是为了说明):

pub fn从\u host()获取\u字符串->&'???CStr{
让ptr:*const c_char=unsafe{ffi.get_string()};
不安全{CStr::from_ptr(ptr)}
}
pub fn消费函数(){
//例如,在这种情况下,这是不可能的
让延长:&'static CStr=get_string_from_host();
//但这应该
let owned=从_host()获取_字符串_到_owned();
}

您的问题和评论列出了您的选项。这主要归结为满足他人的期望,也就是说,最小惊喜原则。这就要求返回一个拥有的
字符串
。如前所述,所拥有的
字符串
包含一个副本(除非在循环中调用无数次,否则对性能的影响可以忽略不计)

我强烈建议不要使用原始指针和
CStr
-参考解决方案,它们是脚踏枪

就个人而言,我会使用闭包,因为它实现了基本情况:访问字符串的代码上下文必须移动到字符串所在的位置;我们不能允许字符串移动到上下文所在的位置(据我们所知,即使调用者也可能无法控制)。
关闭解决方案应该允许您既吃蛋糕又吃蛋糕:类型为
impl-Fn(&CStr)->T的关闭可以是
|s.to_-owned()
,如果需要,使用\u host中的\u string\u制作
,则返回副本。

如果该值在其他操作发生后无效,则调用者有责任正确使用该值。“立即”可能需要将其传递给函数进行处理。这个函数不应该指定无关紧要的规则。要消除任何可能的无效情况,您必须创建一个副本并将其传递回可以无限期使用的地方。@tadman因为如果此函数保证其返回值永远不会离开调用方的作用域,它可以安全地返回字符串作为引用(指向C内存)。它可以证明引用在很短的生命周期内保持有效。因此,不必将其标记为不安全,这对API人体工程学非常有益。制作副本会对性能造成多大影响?您还可以考虑使用这些数据做什么,也许编写安全的执行这些操作的包装器函数,抽象出这个特定的问题?对于许多实际用例来说,性能影响可能是可以忽略的,因为这些字符串非常小,并且这个函数不是从实时线程调用的。但它是一个通用库,所以我不能预测所有用例。出于同样的原因,我也发现很难预测消费者将如何处理这些数据,也很难编写完全定制的包装函数。另外,不仅仅是这一个函数,实际上还有许多函数遵循相同的模式。因此,如果有更好的方法,我肯定会更喜欢。我想你在这里有一个选择,要么以非常繁重的方式摇晃调用者,要么让这个结果的局限性为人所知(不安全),要么制作一个可供使用的安全副本。复制,如果便宜的话,肯定是最好的方法。你的推理(“将代码的上下文移动到字符串所在的位置”)对我来说很有意义,并且使我对闭包方法更有信心。起初我担心这会是一个太异国情调,“太聪明”的选择。。。但现在,我看到它的行动,它感觉相当符合人体工程学。