簡體   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