繁体   English   中英

将 Haskell 字节字符串转换为 C++ std::string

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM