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