Создайте BSTR из ASCIIZ PTR в PowerBasic sqlite3 Wrapper

Я создаю небольшую оболочку для некоторых функций 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).


person Russ    schedule 15.12.2020    source источник
comment
почему тег vb6?   -  person StayOnTarget    schedule 16.12.2020


Ответы (1)


BSTR — это указатель на строку расширенных символов, за которой следует нулевой символ. Слово, предшествующее тексту (у указателя -2), является длиной строки.

Посмотрите на SysAllocString(...) и SysAllocStringLen(...) простые методы создания BSTR из вашего текста UTF-16.

person Jim Mack    schedule 15.12.2020