Julia的String是否为NUL终止?直接传递给ccall的Ptr{Cchar}是否安全?
关于Julia String类型两个特性的解答
问题1:Julia的String类型是否是NUL终止的?
Julia官方实现的String类型,会在底层存储的字节序列末尾额外追加一个不属于字符串本身内容的NUL字节(\0),这个是从0.5版本沿用至今的稳定设计:
- 字符串的
ncodeunits、length返回值不会计入这个额外的NUL字节 - 哪怕字符串本身包含内嵌的NUL字节,末尾的额外NUL依然会存在
这个特性的核心设计目的就是降低和C语言字符串接口的交互成本。
问题2:将字面量"abc"直接传递给期望接收Ptr{Cchar}参数的ccall是否安全?
这种写法在大部分常规场景下可以正常运行,但不推荐,不属于绝对安全的写法,具体说明如下:
可正常工作的前提
满足以下两个条件时直接传String可以得到预期结果:
- 传入的
String本身不包含任何内嵌的\0字节 - C函数仅在
ccall调用过程中读取该字符串,不会长期持有这个指针后续使用(ccall调用期间会自动把传入的String加入GC根集合,不会被回收,调用结束后就没有保护了)
符合上述条件时,因为String末尾自带NUL终止符,可以匹配C端NUL终止字符串的参数预期。
存在的风险
- 没有内嵌NUL检查:如果字符串中意外存在
\0,C函数会在第一个\0位置直接截断,不会抛出任何错误,问题排查成本极高 - 语义不清晰:直接传
String无法明确告知读代码的人,这个参数需要的是NUL终止的C字符串还是普通二进制缓冲区
官方推荐的写法是如果明确要给C传递NUL终止的字符串,就显式使用Cstring包装,它会自动做内嵌NUL检查,代码可读性也更强。
内容的提问来源于stack exchange,提问作者Gnimuc
相关产品推荐
相关产品推荐

