0

いくつかの sqlite3 関数の小さなラッパーを作成しています。

sqlite3.dll には、UTF-16 文字列を返す関数 sqlite3_column_text16() があります。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 ですが、2 番目のバイトはゼロ (null) であるため、これは理にかなっています (と思います)。最初のヌル文字。この場合、ストリングは「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 ではありませんよね? 知らない。

sqlite3_column_text16(ppStmt, 0) によって返された UTF-16 文字列を取り、それを PowerBasic STRING (標準の OLE BSTR) に変換するにはどうすればよいですか。

4

1 に答える 1

1

ABSTRは、ヌル文字が続くワイド文字の文字列へのポインタです。テキストの前 (ポインター -2) の単語は、文字列の長さです。

UTF-16 テキストからを作成する簡単な方法については、SysAllocString(...)およびを参照してください。SysAllocStringLen(...)BSTR

于 2020-12-15T12:38:12.297 に答える