Krótka odpowiedź:
Nie wymagana, jeśli używasz ciągów Unicode, takie jak CString lub wstring konwersji. Użyj sqlite3_open16(). Będziesz musiał upewnić się, że przekazałeś wskaźnik WCHAR (odlany do void *
. Wydaje się być lame! Nawet jeśli ta lib jest platformą crossową, myślę, że mogliby zdefiniować szeroki typ znaku, który zależy od platformy i jest mniej nieprzyjazny niż void *
) do API. Takie jak na CString: (void*)(LPCWSTR)strFilename
Dłuższa odpowiedź:
Nie masz ciąg Unicode, który chcesz przekonwertować na UTF-8 lub UTF16. Masz swój ciąg znaków Unicode reprezentowany w twoim programie przy użyciu danego kodowania: Unicode nie jest reprezentacją binarną jako taką. Kodowanie mówi, w jaki sposób punkty kodowe Unicode (wartości numeryczne) są reprezentowane w pamięci (układ binarny liczby). UTF8 i UTF16 są najczęściej używanymi kodowaniami. Są jednak bardzo różne.
Gdy projekt VS mówi "Zestaw znaków Unicode", oznacza to, że "znaki są zakodowane jako UTF16". Dlatego możesz użyć sqlite3_open16() bezpośrednio. Konwersja nie jest wymagana. Znaki są przechowywane w typie WCHAR (w przeciwieństwie do char
), który zajmuje 16 bitów (Fallback na standardowym typie C wchar_t
, który zajmuje 16 bitów na Win32.Może być inny na innych platformach.Dzięki poprawce, Warcaby).
Jest jeszcze jeden szczegół, na który warto zwrócić uwagę: UTF16 występuje w 2 smakach: Big Endian i Little Endian. To jest uporządkowanie bajtowe tych 16 bitów. Prototyp funkcji, który podajesz dla UTF16, nie mówi, które zamawianie jest używane. Ale jesteś całkiem bezpieczny zakładając, że sqlite używa tej samej endian-ności co Windows (Little Endian IIRC, znam kolejność, ale zawsze miałem problem z nazwami :-)).
EDIT: Odpowiedź na komentarz przez Warcaby:
UTF16 wykorzystuje 16 bitów Kod Jednostki. Pod Win32 (i tylko na Win32), wchar_t
jest używany do takiej jednostki pamięci. Sztuczka polega na tym, że niektóre znaki Unicode wymagają sekwencji 2 takich 16-bitowych jednostek kodu. Nazywane są parami zastępczymi.
W taki sam sposób UTF8 reprezentuje 1 znak przy użyciu sekwencji od 1 do 4 bajtów. Jednak UTF8 są używane z typem char
.
Nie, nie, nie! sqlite3_open16() używa argumentu 'void *', ponieważ jest określony jako UTF16, * NOT * wchar_t, który ma różną wielkość na różnych platformach i może lub nie może być UTF16 (tj. glibc ma 4-bajtowy wchar_t). –
Checkers: zobacz moją odpowiedź jako EDIT tutaj powyżej –
Tak, jestem świadomy reprezentacji UTF16. Nie można jednak zakładać, że wewnętrzna reprezentacja wchar_t jest taka sama na wszystkich platformach, tak nie jest. –