Я создаю небольшую оболочку для некоторых функций sqlite3.
sqlite3.dll имеет функцию sqlite3_column_text16(), которая возвращает строку UTF-16. Это кажется правильной функцией для вызова, поскольку PowerBasic и Windows (и OLE) изначально используют UTF-16 (называемую BSTR), однако, когда я это делаю:
LOCAL pzValue AS ASCIIZ PTR
LOCAL ValLen AS LONG
LOCAL ColText AS STRING
pzValue = sqlite3_column_text16(ppStmt, 0) 'Returns column text ("Russ")
ValLen = sqlite3_column_bytes16(ppStmt, 0) 'Returns the byte length of column text (8)
ColText = &pzValue 'Assign a ASCIIZ PTR to a STRING - ISSUE HERE[/CODE]
ColText содержит только первую букву строки UTF-16.
Это имеет смысл (я думаю), потому что это строка UTF-16, поэтому первый байт является допустимым ASCII, но второй байт равен нулю (null), поэтому в присваивании ColText = &pzValue ColText назначается весь текст до первый нулевой символ. В данном случае это Russ, поэтому байты в UTF-16 равны R0u0s0s0 (за каждым символом ASCII следует ноль (0).
Итак, как мне преобразовать эту строку UTF-16 в строку PowerBasic STRING (которая является BSTR)?
Я проверил некоторые оболочки sqlite3 и нашел этот код (SQLiteningServer.bas):
llColLength = sqlite3_column_bytes(rhSet, llDo)
if llColLength and llColLength <= 253 then
' It is not weird
lsaColumns(llDo) = mkbyt$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
elseif llColLength = 0 then
' Its zero so check type for NULL
if sqlite3_column_type(rhSet, llDo) = 5 then
lsaColumns(llDo) = mkbyt$(254)
else
lsaColumns(llDo) = mkbyt$(0)
end if
else
' It is too long so add a Long
lsaColumns(llDo) = mkbyt$(255) & mkl$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
end if
Итак, в этом коде они делают это:
lsaColumns(llDo) = mkbyt$(llColLength) & peek$(sqlite3_column_blob(rhSet, llDo), llColLength)
Что почти похоже на то, что они строят BSTR в памяти, но не совсем так. Чтобы быть действительным BSTR, начальное числовое значение должно быть INT16, указывающим длину строки в байтах, но в приведенном выше коде они используют начальный BYTE, поэтому это недопустимый BSTR, верно? Я не знаю.
Как взять строку UTF-16, возвращенную sqlite3_column_text16(ppStmt, 0), и преобразовать ее в строку PowerBasic STRING (которая является стандартной OLE BSTR).