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.
The documentation is great!
If you use a
CStringLen, you should have no problems. (In fact, I recommend this because interfacing C++ and Haskell is a nightmare.)NULLcharacters in the middle ofcharbuffers is only problematic when you don’t know how long the data contained therein should be (and thus have to traverse it looking for aNULL, hoping that that’s the intended end of the data).