News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Use of TCHAR in UNICODE build

Started by MichaelK, June 25, 2013, 03:05:14 AM

Previous topic - Next topic

MichaelK

Hello all. I've been searching for hours for a solution to this problem I'm having. I'm having trouble assembling a program making use of TCHAR. ML throws an error saying "constant value too large" when I try to use TCHAR in a Unicode build or even WORD instead of BYTE. Here is an example source:

.386
.model flat, stdcall
option casemap:none

include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib

.DATA
szTitle TCHAR "ASM Application", 0
szMessage TCHAR "Hello, world.", 0

.CODE
start:
invoke MessageBox, 0, ADDR szMessage, ADDR szTitle, MB_OK OR MB_ICONINFORMATION
invoke ExitProcess, 0
end start

And here is the command and parameters I'm trying to build with:

ml /c /Cp /coff /nologo /W3 /D__UNICODE__ /D__NO_NOISE__ /I \masm32\include /Fo obj/main.o src/main.asm

Is there something I'm missing? That's just what I can't seem to figure out :(
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

hutch--

Michael,

have a look at the HLHELP.CHM help file in MASM32. Under the heading Unicode support it explains how it works.

Zen

MICHAEL K.,
Hi. This is one of those weird problems where the solution is not obvious.
As you know, WINDOWS defines a TCHAR as a single byte character, using the ASCII standard codes,...unless, UNICODE is defined,...then, a TCHAR is defined as a two-byte Unicode character.
Most assembly programmers just use the single-byte character codes  because we all speak English. I think the problem is (and HUTCH mentioned this in a thread monthes ago), that the MASM copmpiler only recognizes the single-byte definition (which doesn't conform to the WINDOWS data type definition).
The solution is simple: find the MASM definition file and alter (temporarily) the value of the TCHAR character, to the double-byte UNICODE type.

Added as an edit: (OOPS,...HUTCH got the answer ahead of me)

dedndave

i had this problem a while back
moreover, i wanted the LENGTHOF operator to return the number of characters, whether it was built for UNICODE or ANSI

qWord (forum member) gave me a nice solution that i have been using without problems, since

;###############################################################################################

;tchr macro by qWord

tchr    MACRO   lbl,args:VARARG
    IFDEF __UNICODE__
        UCSTR lbl,args
    ELSE
        lbl db args
    ENDIF
        ENDM

;###############################################################################################

        .DATA

tchr szNoFile,   'No File Specified',0
tchr szTooBig,   'File Too Large',0
tchr szNotFound, 'File Not Found',0
tchr szAlready,  'File Already Exists',0
tchr szInpFile,  'Input File:',13,10,0
tchr szOutFile,  'Output File:',13,10,0

;***********************************************************************************************

MichaelK

Thank you everyone for your replies. Though the docs do not state it clearly, my understanding is that you cannot use TCHAR to statically initialize a variable but only dynamically. Like so:

szBuffer TCHAR "Some text", 0   ; Error
szBuffer TCHAR 50 DUP(0)        ; OK


Also, when I try to use UCSTR like in the help file, ML throws a syntax error. Like this:

UCSTR szBuffer, "Some text", 0


Am I missing something like an include file? I'm using the same include files like the one in my original post.
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

dedndave

UCSTR szBuffer, "Some text", 0

that assembles ok, here
make sure you are in either the .DATA or .CODE section (.CONST will also work)  :P

MichaelK

Unfortunately, not on my system. The whole program is exactly like the original one I posted except the inclusion of the UCSTR line (in the data section), but ML generates the following error message:
error A2008: syntax error : UCSTR
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

dedndave

ok
you have to include more files   :P

in this case, specifically \masm32\macros\macros.asm

but - to make things simple, get rid of the entire preamble and

include \masm32\include\masm32rt.inc

that file takes care of casemap, processor, model, and a number of includes

MichaelK

Thanks. It works perfectly now  :biggrin:
Would you recommend editing masm32rt.inc to include qWord's code snippet so the use of TCHR when in Unicode mode or otherwise becomes transparent?
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

dedndave

no - i only edit the masm32 files when a bug is found
otherwise, you will not be compatible with other forum members
you post a program that you can assemble, but others cannot - lol

put it in a seperate file
what i quite often do is to create an INC file for the project - that would be a good place

MichaelK

Got it. So I've created a separate include file to take care of that. This is how it looks (I modified the original snippet to use qWord's UCCSTR macro to enable support for escape sequences too):

TCHR MACRO lbl, args :VARARG
IFDEF __UNICODE__
UCCSTR lbl, args
ELSE
lbl db args
ENDIF
ENDM


I got a feeling today is gonna be awesome for me. Good start!  :eusa_dance:
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

dedndave

TCCHR MACRO lbl, args :VARARG
IFDEF __UNICODE__
UCCSTR lbl, args
ELSE
lbl db args
ENDIF
ENDM


spot the difference ?   :biggrin:

MichaelK

Pardon me to resurrect this dead thread. But what's the difference between "TCHR" and "TCCHR". AFAIK, "TCHR" isn't defined anywhere.  :icon_confused:
So [or eax, 0FFh] == [mov eax, -1]? Not again, asm!

dedndave

TCCHR must be the name of someone's macro

TCHR is the name used by qWord for his macro
i prefer this macro because it returns correct values when used with LENGTHOF and SIZEOF operators
TCHR    MACRO lbl,args:VARARG

    IFNDEF __UNICODE__
        lbl db args
    ELSE
        UCSTR lbl,args
    ENDIF

        ENDM

dedndave

declare the macro early in the source (it generates no code)

then, to use it....
    .DATA

TCHR  szString,"MyString",0


now, it generates the correct ANSI string if the __UNICODE__ symbol is not defined
or the correct UNICODE string if the __UNICODE__ symbol is defined