The problem with a number of API functions is that they return strings as LPSTR. An LPSTR is a pointer to a string in memory that is terminated with null (0x00 byte), and the strings themselves are in an ANSI format, not UNICODE. And the string length isn't stored anywhere. Meanwhile in VB6, its strings are of the BSTR type. These are pointers to UNICODE strings, and while these are terminated with a unicode null (0x0000 word), they also have a byte count in the 4 bytes before the start of the string. Note that this does not include the 2 byte null at the end.
To convert between LPSTR and BSTR, I've created these 2 functions. Put the below code into a module in VB6.
To test out these functions, put the below code into your Form1, and make sure the AutoRedraw property is set to True for Form1, then run the program.
If it is working correctly on your computer, the sentence "This is a test." should appear 3 times on the form, and then the numbers 15, 256, and 15 should appear. The 2 15s are the sizes of the original BSTR string, and BSTR string that was created from the LPSTR string that was created from the original BSTR string. The 256 is the size of the block of memory in which the LPSTR was stored. The block of memory in which the string that pointed to by the LPSTR is stored, must be no smaller than the length of the string, but it can be larger than that length without a problem (as this program demonstrates).
To convert between LPSTR and BSTR, I've created these 2 functions. Put the below code into a module in VB6.
Code:
Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Public Sub BSTR2LPSTR(ByVal BSTR As String, ByVal LPSTR As Long)
Dim STR() As Byte
STR() = StrConv(BSTR & vbNullChar, vbFromUnicode)
CopyMemory ByVal LPSTR, STR(0), UBound(STR) + 1
End Sub
Public Function LPSTR2BSTR(ByVal LPSTR As Long, Optional ByVal NullSearchDist As Long = 256) As String
Dim STR() As Byte
Dim NullOffset As Long
Dim StrLen As Long
ReDim STR(NullSearchDist - 1)
CopyMemory STR(0), ByVal LPSTR, NullSearchDist
NullOffset = InStrB(1, STR, StrConv(vbNullChar, vbFromUnicode)) - 1
Select Case NullOffset
Case -1
StrLen = NullSearchDist
Case 0
StrLen = 1
Case Else
StrLen = NullOffset
End Select
ReDim Preserve STR(StrLen - 1)
LPSTR2BSTR = StrConv(STR, vbUnicode)
End Function
To test out these functions, put the below code into your Form1, and make sure the AutoRedraw property is set to True for Form1, then run the program.
Code:
Private Sub Form_Load()
Dim a As String
Dim b() As Byte
Dim ptrb As Long
Dim c As String
Dim n As Long
ReDim b(255)
ptrb = VarPtr(b(0))
a = "This is a test."
BSTR2LPSTR a, ptrb
c = LPSTR2BSTR(ptrb)
Print a
For n = 0 To 255
If b(n) = 0 Then Exit For
Print Chr$(b(n));
Next n
Print ""
Print c
Print Len(a)
Print UBound(b) + 1
Print Len(c)
End Sub