将 Haskell ByteString 转换为 C++标准::字符串

发布于 2024-11-10 08:07:07 字数 1011 浏览 5 评论 0原文

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

当前解决方案

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

一些 c++ 库文档 内容如下:

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

Content 被初始化为由 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 指出的那样。

I want to convert strict ByteStrings from Haskell into C++'s std::string to pass it to a C++ library via the FFI. As the ByteString may contain NULL characters, converting into a CString as an intermediate step is not viable. What is the right approach here?

current solution

Thanks for the answers so far. I hoped for a canonical solution for that task, but maybe it does not exist yet :)

Some c++ library documentation says following:

string ( const char * s, size_t n );

Content is initialized to a copy of the string formed by the first n characters in the array of characters pointed by s.

Therefore one can write such a function which copies once from the ByteString to construct a 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)

The C++ code accompanying toCCString_ then would just look like Neil and Alan pointed out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自此以后,行同陌路 2024-11-17 08:07:07

文档很棒!

类型 CString = Ptr CChar

<块引用>

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

类型 CStringLen = (Ptr CChar, Int)

<块引用>

具有显式长度信息(以字节为单位)的字符串,而不是终止 NUL(允许字符串中间存在 NUL 字符)。

如果您使用CStringLen,则应该没有问题。 (事实上​​,我推荐这样做是因为 C++ 和 Haskell 的接口是一场噩梦。)

仅当您不知道其中包含的数据应该有多长(因此必须遍历它)时,char 缓冲区中间的 NULL 字符才会出现问题寻找 NULL,希望这是数据的预期结尾)。

The documentation is great!

type CString = Ptr CChar

A C string is a reference to an array of C characters terminated by NUL.

type CStringLen = (Ptr CChar, Int)

A string with explicit length information in bytes instead of a terminating NUL (allowing NUL characters in the middle of the string).

If you use a CStringLen, you should have no problems. (In fact, I recommend this because interfacing C++ and Haskell is a nightmare.)

NULL characters in the middle of char buffers is only problematic when you don't know how long the data contained therein should be (and thus have to traverse it looking for a NULL, hoping that that's the intended end of the data).

耶耶耶 2024-11-17 08:07:07

您的 ByteString (及其空值)实际上代表文本字符串吗?如果没有,那么 std::vector 会更合适。

话虽这么说, std::string 的内部表示不依赖于 null 终止,因此您可以拥有一个包含 null 字符的 std::string 。使用带有原型 string(const char * s, size_t n) 的构造函数 。只是不要依赖 .c_str() 来与任何期望以 null 结尾的 c 字符串进行交互。

Does your ByteString (with its nulls) actually represent a text string? If not, then std::vector<char> would be more appropriate.

That being said, the internal representation of std::string does not depend on null termination so you can have a std::string with null characters in it. Use the constructor with the prototype string(const char * s, size_t n). Just don't depend on .c_str() to interface with anything expecting a null terminated c string.

望她远 2024-11-17 08:07:07

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

char s1[] ="string containing nulls";

那么你可以转换为 std::string

string s2( s1, length_of_s1 );

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

C++ strings can contain null characters. Assuming you have something like this:

char s1[] ="string containing nulls";

then you can convert to a std::string

string s2( s1, length_of_s1 );

The problem is how to get length_of_s1 - obviously you can't use strlen, or similar functions, but presumably your strings are maintaining a length indicator you can use.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文