2012-12-15 93 views
6

目前我正在寫一個插件,它只是一個現有庫的包裝。 插件的主機傳給我一個utf-16格式化的字符串,定義如下如何將utf16 ushort數組轉換爲utf8 std :: string?

typedef unsigned short PA_Unichar;

而且包裹庫只接受一個const char *或爲std :: string UTF-8格式的字符串 我試着寫一個轉換功能像

std::string toUtf8(const PA_Unichar* data) 
{ 
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert; 
return std::string(convert.to_bytes(static_cast<const char16_t*>(data)); 
} 

但顯然這是不行的,我扔一個編譯錯誤「static_cast從'const指針'(aka'const unsigned short *')到'const char16_t *'是不允許的」

那麼最優雅/正確的方法是什麼?

預先感謝您。

+0

在你的平臺上'std :: is_same :: value'的值是多少?另外,哪個編譯器? – moshbear

+0

'std :: is_same :: value'的值爲0(false),我正在使用Apple LLVM編譯器4.1在Mac上進行編譯,儘管我也使用Visual Studio 2012進行交叉編譯 – Robotex

+1

根據http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2018.html,'char16_t'是'uint16_least_t',而不是'uint16_t'。在你的平臺上,'uint16_least_t'看起來像* unsigned short,因此'sizeof(char16_t)!= sizeof(unsigned short)'。當底層的'sizeof's不匹配時'static_cast'將會在指針類型上失敗。 – moshbear

回答

2

你可以使用basic_string(Iterator, Iterator)構造的PA_unichar字符串轉換成的char16_t一個字符串,然後使用std::codecvt_utf8_utf16的小面你嘗試:

std::string conv(const PA_unichar* str, size_t len) 
{ 
    std::u16string s(str, str+len); 
    std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert; 
    return convert.to_bytes(s); 
} 

認爲這是正確的。不幸的是,我無法測試這個,因爲我的實現還不支持它。我有一個執行wstring_convert,我打算包含在GCC 4.9中,但是我沒有執行codecvt_utf8_utf16來測試它。

+0

非常感謝你,它似乎工作得很好,這也使我從一些可怕的類型演員中拯救了我:) – Robotex

+0

太好了,我很高興我頭腦中的編譯器得到了類型檢查的權利!出於興趣,您使用哪種編譯器支持這些類? –

+0

我在基於Mac的系統上編譯LLVM 4.1編譯器(在設置標誌'-std = C++ 11'後)和Windows系統上的Visual Studio 2012 – Robotex