G'day everyone
I'm a bit confused with the result I'm getting from ucLen. Into a DLL I'm passing, from VB, by reference, strings containing UTF8, UTF16 and UTF32 encoded data. So far as the documentation is concerned, VB is supposed to be sending in a BSTR, but I can't declare something in MASM32 as being a BSTR (or so it seeems). The closest I can get is LPWSTR. Nevertheless, I put the parameter in ECX, subtract 4 and hope that I'm looking at the BSTR's header where it says how many bytes are in the string but I get strange results.
HandleStringByRef proc STDCALL aString:LPWSTR
mov ecx, aString
sub ecx, 4
mov eax, [ecx]
; xor eax, eax
; mov ax, word ptr [ecx]
fn MessageBox, NULL, sstr$(eax), SADD("Length by Looking"), MB_OK
fn ucLen, aString
fn MessageBox, NULL, sstr$(eax), SADD("Length by Reference"), MB_OK
fn MessageBox, NULL, aString, SADD("String by Reference"), MB_OK
ret
HandleStringByRef endp
It's bound to be something obvious.
Ideas?
Kind regards,
Bruce.
The trick with strings in VB is that a BSTR is actually a pointer. So when you pass ByVal, you are passing a pointer to the string (with the length in the DWORD prior to where this pointer points). To get a pointer to the string you need to dereference it once. If you pass ByRef, you are passing a pointer to the BSTR, which means you need to dereference twice to get to the start of the string.
Also, when passing strings to external functions in VB, they are all converted to ANSI. Also, any returned strings are converted from ANSI to wide-encoding. If you embed a type library in your DLL VB will pass wide strings, which is how they are stored internally, but this tends to be more trouble than it's worth.
IMHO, you are best to call the parameter in MASM a DWORD rather than any other 'type'. Alternatively, you should be able to safely BSTR typedef DWORD though this achieves little besides hiding the true nature of the variable.
Cheers,
Zooba :U
Thanks, Zooba, for your help. As it was I discovered yet another way around the 'converted to ANSI' issue: use an undocumented feature of VB called strptr, which is discussed in http://vb.mvps.org/tips/varptr.asp
Now I can pass anything to my DLL, be it UTF8, UTF16, UTF32, ISCII, or whatever, because I'm not passing the string, but rather the address of the string. Now SysStringByteLen actually tells me the truth.
I'm quite excited. So's the boss. MASM32 is not going to be a WOMBAT (Waste Of Money, Brains And Time) after all.
Kind regards,
Bruce.