いくつかの 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) に変換するにはどうすればよいですか。