News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

LPWSTR etc

Started by axtens, April 16, 2007, 08:56:41 AM

Previous topic - Next topic

axtens

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.


zooba

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

axtens

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.