“Rust设计模式学习笔记8-10。”
一、FFI错误处理惯常做法
1、惯常做法一:简单枚举类型应该被转换为整数,并作为代码返回。
代码示例如下:
2、惯常做法二:结构化枚举应该被转换为整数代码,并有字符串错误信息作为提示细节。
代码示例如下:
然后在导出给外部语言使用的函数中,对于具体的错误,可以加上字符串错误信息作为提示。
3、惯常做法三:自定义错误类型应该变的透明,用c表示。
示例代码如下:
原因:保证外部语言清晰的获取错误信息,同时完全不影响Rust代码的API。
二、FFI接受字符串处理
1、惯常做法
当FFI接受字符串时,应该遵循:
使用外部字符串时尽量是借用,而不是直接复制它们;
尽量减少从C风格字符串转换到Rust字符串时的复杂性,尽量减少unsafe代码量。
2、第一条的原因
因为C语言中使用的字符串和Rust中使用字符串存在不同的行为:
C语言字符串时无终止的,Rust字符串会存储其长度;
C语言字符串可以包含任意非零字节,Rust字符串必须是UTF-8;
C语言字使用unsafe的指针操作字符串,Rust使用安全的方法与字符串进行交互。
3、第二条的原因
显而易见,不做解释
4、其它
Rust标准库提供了CString和&CStr,是String和&str相对于C语言的等价表示,使用它们可以降低Rust和C之间字符串操作代码的复杂性,也可以减少unsafe的代码量。
三、FFI传递字符串
1、通常做法
向FFI函数传递字符串应遵循四个原则:
字符串的生命周期尽可能长;
转换过程尽量减少unsafe代码;
如果C代码可以修改字符串,使用Vec而不是CString;
除非外部API要求,否则字符串的所有权不应该转移给被调用者。
2、示例
重点看看下面这个例子(非常重要):
第一种方式在unsafe代码块之外创建CString,其作用域范围一直到13行,因此在unsafe中使用其指针一定是有效的;第二种方式相当于用临时变量直接as_ptr(),无法保证在unsafe中一直有效。
按照《Rust设计模式》书中的说法,第二种方式将导致一个悬垂指针。
领取专属 10元无门槛券
私享最新 技术干货