【问题标题】:Convert Haskell ByteStrings to C++ std::string将 Haskell ByteStrings 转换为 C++ std::string
【发布时间】:2011-09-02 16:16:23
【问题描述】:

我想将严格的 ByteStrings 从 Haskell 转换为 C++ 的 std::string 以通过 the FFI 将其传递给 C++ 库。由于ByteString 可能包含NULL 字符,因此转换为CString 作为中间步骤是不可行的。这里的正确方法是什么?

当前解决方案

感谢到目前为止的回答。我希望该任务有一个规范的解决方案,但也许它还不存在:)

一些c++ library documentation 说如下:

字符串 ( const char * s, size_t n );

内容被初始化为由 s 指向的字符数组中的前 n 个字符组成的字符串的副本。

因此可以编写这样一个函数,从 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 指出的那样。

【问题讨论】:

  • 我们需要更多关于您打算如何连接这两种语言的信息。
  • 我稍微编辑了我的问题,但我不确定你的意思是什么信息。
  • “通过 FFI”是我们需要的。
  • 对不起,我之前编辑过“CString”。当时不知道这是一个具体的事情。已恢复。

标签: c++ string haskell ffi


【解决方案1】:

documentation 很棒!

type CString = Ptr CChar

C 字符串是对以 NUL 结尾的 C 字符数组的引用。

type CStringLen = (Ptr CChar, Int)

具有明确长度信息(以字节为单位)的字符串,而不是终止 NUL(允许字符串中间出现 NUL 字符)。

如果您使用CStringLen,您应该没有问题。 (其实我推荐这个是因为interfacing C++ and Haskell is a nightmare。)

char 缓冲区中间的

NULL 字符只有在您不知道其中包含的数据 应该 多长时间(因此必须遍历它寻找 @ 987654326@,希望这是数据的预期结束)。

【讨论】:

    【解决方案2】:

    你的ByteString(带有它的空值)实际上代表一个文本字符串吗?如果不是,那么std::vector<char> 会更合适。

    话虽如此,std::string 的内部表示不依赖于空终止,因此您可以拥有一个包含空字符的 std::string。使用constructor with the prototype string(const char * s, size_t n)。只是不要依赖 .c_str() 来与任何期望以 null 终止的 c 字符串交互的东西。

    【讨论】:

    • Binary 或 Cereal 的输出具有包含 NULL 的标头,其中需要指示后续数据的大小。这些数据是否只是文本数据并没有预先确定。
    • @Long:听起来 std:vector 会更适合您的使用。您在缓冲区上使用了任何实际的特定于字符串的函数吗?
    • 我正在编写与 Xapian 搜索库的绑定,它在内部将任何用户定义的额外信息(从简单的字符串到复杂的数据结构)存储为 std::string。知道这一点,我认为使用 std::vector 只是一个不必要的中间步骤。
    【解决方案3】:

    C++ 字符串可以包含空字符。假设你有这样的东西:

    char s1[] ="string containing nulls";
    

    然后你可以转换为 std::string

    string s2( s1, length_of_s1 );
    

    问题是如何获得length_of_s1 - 显然你不能使用 strlen 或类似的函数,但大概你的字符串维护了一个你可以使用的长度指示器。

    【讨论】:

    • 我不明白这如何以任何方式回答这个问题。
    猜你喜欢
    • 1970-01-01
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-28
    相关资源
    最近更新 更多