[英]Convert Haskell ByteStrings to C++ std::string
我想将 Haskell 中的严格ByteStrings
转换为 C++ 的std::string
以通过FFI将其传递给 C++ 库。 由于ByteString
可能包含NULL
字符,因此将转换为CString
作为中间步骤是不可行的。 这里的正确方法是什么?
当前解决方案
感谢您到目前为止的答案。 我希望该任务有一个规范的解决方案,但也许它还不存在:)
一些c++ 库文档说明如下:
字符串 ( const char * s, size_t n );
内容被初始化为由 s 指向的字符数组中的前 n 个字符组成的字符串的副本。
因此,可以编写这样一个 function 从 ByteString 复制一次以构造 std::string
foreign import ccall unsafe toCCString_ :: CString -> CUInt -> IO (Ptr CCString)
toCCString :: ByteString -> IO (Ptr CCString)
toCCString bs =
unsafeUseAsCStringLen bs $ \(cstring,len) ->
toCCString_ cstring (fromIntegral len)
伴随toCCString_
的 C++ 代码看起来就像 Neil 和 Alan 指出的那样。
文档很棒!
类型 CString = Ptr CChar
C 字符串是对以 NUL 结尾的 C 字符数组的引用。
类型 CStringLen = (Ptr CChar, Int)
具有以字节为单位的显式长度信息的字符串,而不是终止 NUL(允许字符串中间有 NUL 字符)。
如果您使用CStringLen
,则应该没有问题。 (事实上,我推荐这个,因为连接 C++ 和 Haskell 是一场噩梦。)
char
缓冲区中间的NULL
字符只有在您不知道其中包含的数据应该多长时间时才会出现问题(因此必须遍历它以寻找NULL
,希望这是数据的预期结束)。
您的ByteString
(带有它的空值)实际上代表一个文本字符串吗? 如果不是,那么std::vector<char>
会更合适。
也就是说,std::string 的内部表示不依赖于 null 终止,因此您可以拥有一个带有 null 字符的 std::string 。 使用带有原型 string(const char * s, size_t n) 的构造函数。 只是不要依赖 .c_str() 来连接任何期望 null 终止的 c 字符串的东西。
C++ 字符串可以包含 null 字符。 假设你有这样的事情:
char s1[] ="string containing nulls";
然后您可以转换为 std::string
string s2( s1, length_of_s1 );
问题是如何获得length_of_s1
- 显然你不能使用 strlen 或类似的函数,但大概你的字符串正在维护一个你可以使用的长度指示器。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.