VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- From: "MarkJackson" <mark@xxxxxxxxxx>
- Date: 6 Sep 2005 05:05:42 -0700
Hi
Briefly:
I have a Fortran DLL that returns a structure containing fixed-length
strings to a VB6 program. Fine for English characters, but not for
returning Chinese characters (using Chinese code page on the PC). In my
debugger the strings are correct in the DLL, but in the VB there are
garbage characters at the end. I can only think that VB's implicit ANSI
to Unicode conversion has messed up. Can anyone help with this?
Details, with code:
I'm calling a DLL from VB6 with a Declare statement, passing a
structure containing fixed-length strings of length 20 characters.
Behind the scenes VB creates a copy of the structure with ANSI strings
of 20 bytes. When the DLL returns, VB converts the strings from ANSI to
Unicode and copies the data back to the original structure.
If the DLL writes one Chinese character at the start of a 20 byte
string, that takes 2 bytes (in ANSI encoding). It pads with spaces,
making 19 characters in the 20 bytes. VB implicitly converts the
strings from ANSI to Unicode when the DLL returns. Those 19 characters
convert fine, but the 20th character in the VB string is garbage. VB
seems to just interpret the next two bytes in the structure (past the
end of the string!) as a Unicode character. And I don't mean it
converts them from ANSI! If the next two bytes are both hex 0x20, you
don't get a space, you get the Unicode character 0x2020.
I'm not going to explain why we're using Fortran DLLs, but there are
reasons! I think the same would happen with a C DLL but don't have time
to test it now. (I'm using Compaq Visual Fortran 6 by the way)
VB source code, in a form with a button:
>>>
Private Type testStruct
sTestOne As String * 20
bytArray(0 To 20) As Byte
End Type
Private Declare Function TestDllFunction Lib "test32.dll" (ByRef
nTestNum As Integer, ByRef testStruct As testStruct) As Integer
Private Sub cmdTest_Click()
Dim i As Integer
Dim testRec As testStruct
Dim nNumChars As Integer
'Put some marker bytes past the string to help diagnose problem
For i = 0 To 20
testRec.bytArray(i) = 32 + i
Next i
nNumChars = 1
i = TestDllFunction(nNumChars, testRec)
Debug.Assert False
'Check testRec.sTestOne here - one garbage character at the end
'for each Chinese character returned
End Sub
<<<<
DLL source code. Fortran, but hopefully readable? ACHAR is like Chr$,
and I've hardcoded the ANSI encodings for the Chinese characters from 1
to 10
>>>>
INTEGER*2 FUNCTION TestDllFunction
+ (nNumChars, testRec )
IMPLICIT NONE
!DEC$ ATTRIBUTES DLLEXPORT::TestDllFunction !
This exports the name from the DLL
!DEC$ ATTRIBUTES ALIAS : "TestDllFunction" :: TestDllFunction !
This makes the name accessible to VB6
C ---
INTEGER*2 nNumChars
STRUCTURE /testStruct/
CHARACTER*20 sTestOne
INTEGER*1 bytArray(0:20)
END STRUCTURE
RECORD /testStruct/ testRec
INTEGER*2 i
C ---
!The Chinese characters for one to ten,
!when interpreted on simplified Chinese code page (936)
testRec%sTestOne(1:2) = ACHAR('D2'X) // ACHAR('BB'X)
testRec%sTestOne(3:4) = ACHAR('B6'X) // ACHAR('FE'X)
testRec%sTestOne(5:6) = ACHAR('C8'X) // ACHAR('FD'X)
testRec%sTestOne(7:8) = ACHAR('CB'X) // ACHAR('C4'X)
testRec%sTestOne(9:10) = ACHAR('CE'X) // ACHAR('E5'X)
testRec%sTestOne(11:12) = ACHAR('C1'X) // ACHAR('F9'X)
testRec%sTestOne(13:14) = ACHAR('C6'X) // ACHAR('DF'X)
testRec%sTestOne(15:16) = ACHAR('B0'X) // ACHAR('CB'X)
testRec%sTestOne(17:18) = ACHAR('BE'X) // ACHAR('C5'X)
testRec%sTestOne(19:20) = ACHAR('CA'X) // ACHAR('AE'X)
!Pad any leftover with spaces
DO i=(nNumChars*2)+1, 20
testRec%sTestOne(i:i) = ACHAR(32)
END DO
C ---
TestDllFunction=1
RETURN
END
<<<<
.
- Follow-Ups:
- Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- From: Mark Yudkin
- Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- From: Someone
- Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- From: Norman Diamond
- Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- From: Tony Proctor
- Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- Prev by Date: Re: GetAttr() of nonexistent file, Windows XP <> 98 ?
- Next by Date: Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- Previous by thread: Access Violation
- Next by thread: Re: VB6 ANSI to Unicode conversion wrong with fixed-length strings in structures
- Index(es):