这一篇我们来探讨Rust导出共享库时如何传递字符串,主要涉及字符串作为函数参数和函数返回值的处理细节。我们首先回顾关于字符串的基础知识,了解其在Rust和C中的区别,然后设计具体的示例进行实践,并整理出传递字符串的FFI编程范式。
基础知识
在 C 语言中,字符串可看作是由字符组成的一维的字节数组。但在内存中具体如何保存每个字符,这依赖于特定的字符编码。字符串常量默认是以 NUL 字符结尾,通常用转义序列'\0'
表示,由 C 编译器自动添加。
字符串可以用指针和字节数组来表示,这是两种不同方式的存储:
将字符串存储在字符类型的数组中时,最初,字符串是字节序列,其中每个字节代表一个字符。但后来为了表示宽字符,ISO C 标准引入了新类型。一般,char
表示ASCII和UTF-8编码,wchar_t
表示UTF-16等“宽”字符编码。
大多数字符串和I/O库函数都采用char *
参数,该参数表示指向字符串中的第一个字符(即存储该字符串的数组的第一个元素)。由于传递给函数的是第一个元素的地址,因此该函数并不知道数组有多大,只能依靠空终止符来判断何时停止处理。
1)共享的只读字符串 char *
。在大多数编译器中,将字符串字面量直接分配给指针后,字符串常量被存储于初始化数据段的只读(.roadata)区域,而指针变量被存储于读写区域中,也就是说可以更改指针以指向其它内容,但不能更改字符串常量的内容。因此&