You all probably know that all API's that accept strings have both ANSI and Unicode versions (like MessageBoxA and MessageBoxW). However, MASM32 comes with prototypes for only the ANSI versions.

Win9x does not support unicode, but when Unicode API's are used, all strings are first converted to ANSI, and returned strings are translated back to Unicode. Win2000 and the like do the opposite, internally only using Unicode strings.

You can imagine the overhead of having all of your ANSI strings converted to Unicode and back when calling ANSI functions on Win2000. That's why I propose that Unicode prototypes should be included in all MASM32 include files (that is, all the prototypes).

PS. I'm not saying to replace all the 'regular' API's to only represent Unicode, like this...

MessageBoxExW PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
MessageBoxEx equ <MessageBoxExW>

Something like this would be better...

MessageBoxExA PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
MessageBoxExW PROTO :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
MessageBoxEx equ <MessageBoxExA>

.. so that people have a choice.
Posted on 2002-07-29 13:29:20 by Paulicles the Philosopher
The solution is a utility that is already included in MASM32 called lib2incW.exe.

Create a set of your own unicode include files and write you own unicode code.

MASM32 is basically ANSI only as they is where the demand is so most of the example code and the libraries are set for ANSI but you can write your own stuff there.

Note that Ernie Murphy has done some unicode work including libraries in his COM work.

Regards,

hutch@movsd.com
Posted on 2002-07-29 21:20:59 by hutch--
Hi Paulicles the Philosopher, you wrote: You can imagine the overhead of having all of your ANSI strings converted to Unicode and back when calling ANSI functions on Win2000. That's why I propose that Unicode prototypes should be included in all MASM32 include files (that is, all the prototypes).
Here is a passionate advice, if you allow me to give you one:
I can understand your concern, but most of the times we tend to give too much importance to this kind of problems. In fact, if you measure it, you will realize that there's such a high "costant" overhead in calling Win32 functions that if it does some more work it will not really have any significative influence on the total Win32 function call time.
Before spending your precious development time on something that may not be worth, it would be better to test what will be the gain vs the work involved.
You can do with this advice whatever you want ;) ..but I think that one of the best and most important optimizations is optimizing the own development time.
Posted on 2002-07-30 02:30:40 by Maverick
I'm with maverick... and furthermore, your program might get slower if
you start working with unicode strings (double string lengths, 16bit chars
(remember 16bit data manipulation is slow on 32bit processors), etc).
Unless you *really* need unicode, I'd advice you to stick with ANSI or OEM.

Anyway, I've attached my "protoize" program. It generates three include
files per import library you run it on: one with neutral, one with ansi, and
one with unicode includes. You should define symbols "INCLUDE_ANSI"
and/or "INCLUDE_UNICODE" to select which will be included, and "PREFER_ANSI"
*or* "PREFER_UNICODE" to select (for example) whether MessageBox maps
to MessageBoxA or MessageBoxW. It generates full protos (including STDCALL),
so you are free to use other global calling conventions if you wish. It should
also handle symbols with non-stdcall conventions (C-call, SYSCALL).
Posted on 2002-07-30 07:49:40 by f0dder
I'm going to have to disagree with you guys. But before I say anything more, I want to thank hutch for pointing out that utility.

1) Let's say that you are using ANSI strings with Unicode functions. The operating system would have to do all those slow 16-bit operations twice on your strings for conversion.

2) < + 2*. Isn't one of the reasons for using assembly faster code?

3) Is using Unicode really that hard? You're just using WORDs, not BYTEs. The biggest thing is having to use the 'L' macro which comes with COLIB.

4) If development time optimization is so important, use Visual C++ or "better yet" Visual Basic: you can create an {internet , ActiveX, Automation}-ready application in seconds without lifting a finger, and all you have to do is dynamically link your app to a morbidly overweight DLL. :alright:
Posted on 2002-07-30 12:48:06 by Paulicles the Philosopher
I'm mostly sitting dead center on the fence here, bit if the wind was in the right direction, I'd be leaning to Paulicles' side. Here's why:

Unicode (if you don't care to admit it) IS the future. Period. It's necessary to support all those silly 'legacy' countries who don't speak english.

MS has quietly added Unicode support into their windows .h files for some time now. These files contain protos for both the 'A' and 'W' procedure versions, and a conditional compilation to pick a default if neither A nor W is chosen.

That default is 'A,' unless the constant 'Unicode' is defined. MASM32 however, simply redirects the unspecied function calls to the 'A' verions.

I would stongly suggest any attempts to include Unicode support follow the MS example for the sake of uniformity.

That said, I'm personally not motivated enough to go back and modify any of the .inc files to do such a conditional switch. The furthest I've gone is to define the proto for MessageBoxW inside user32.inc, as that is one of the very few Unicode functions that every variant of Windows supports (W95/W98 being the slackers here).

That proto lets me check strings when I find it necessary to use (and verify) Unicode strings.


Changing (and validating!) the very large and stable codebase of the MASM32 include files is not to be taken lightly!
Posted on 2002-07-30 16:41:38 by Ernie

That said, I'm personally not motivated enough to go back and modify any of the .inc files to do such a conditional switch.

Then use my protoize tool ;)
Posted on 2002-07-30 16:46:32 by f0dder
I am trying to use makefiles to build both Unicode and ANSI versions of an app. Unfortunately, the /d flag doesn't seem to work. What I want to do is something like this.



ml ... /dUNICODE ...


IFDEF UNICODE

include inclw\kernel32.inc
CHAR EQU <WORD>
_TEXT EQU <L> ;; Link to 'L' macro

ELSE

include incla\kernel32.inc
CHAR EQU <BYTE>
_TEXT EQU <ANSI> ;; ANSI() is a macro that is compatible with
;; L's escape characters but returns an ANSI str.
ENDIF

....
myString CHAR _TEXT(<Hello, World\|>)


Have any of you guys even gotten the /d flag to work for ML?
Posted on 2002-08-01 11:53:07 by Paulicles the Philosopher
Maybe it has to be /D ?
I use the following all the time:
ML /c /coff /nologo /DUNICODE %1.asm
Should also be able to do:
ML /c /coff /nologo /DUNICODE=1 %1.asm

Also, you can use this bit of code to test it during assemble-time:
	xxx TEXTEQU %UNICODE

% ECHO xxx
...the first line converts the number to text and the second displays it on the screen.
Posted on 2002-08-01 17:08:03 by bitRAKE
Thanks for the tip, bitRAKE. I'd try it out now, but my computer's all screwed up.
Posted on 2002-08-01 21:09:07 by Paulicles the Philosopher