Pelles C forum
C language => Pocket PC and Smartphone questions => Topic started by: iancasey on May 09, 2009, 10:42:07 PM
-
Hi all,
I have a problem with string lengths, I was trying out PellesC 32 bit unicode for Win32 and noticed this difference:
For PPC this works:
_TCHAR *left (_TCHAR *S, int length)
{
register int tmplen = _tcslen(S);
if(length<1) return BCX_TmpStr(1);
if(length<tmplen) tmplen=length;
_TCHAR *strtmp = BCX_TmpStr(tmplen);
return (_TCHAR*)memcpy(strtmp,S,tmplen*sizeof(_TCHAR));
}
for Win32 Unicode I must change the last line to
return (_TCHAR*)memcpy(strtmp,S,tmplen) //- no sizeof
This is a BCX function so I was wondering which version is correct to use
Is this a bug in PPC or Win32 Unicode version?
Ian
-
What does the BCX_TmpStr function do? I assume it allocates something - bytes or (_TCHAR-) characters?
-
Pelle,
I appended the original BCX code and the converted unicode code for BCX_TmpStr, I believe it a circular buffer for temporary variables.
Original BCX Code:
char *BCX_TmpStr (size_t Bites)
{
static int StrCnt;
static char *StrFunc[2048];
StrCnt=(StrCnt + 1) & 2047;
if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
}
BCX Code converted to unicode:
_TCHAR *BCX_TmpStr (size_t Bites)
{
static int StrCnt;
static _TCHAR *StrFunc[2048];
StrCnt=(StrCnt + 1) & 2047;
if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
return StrFunc[StrCnt]=(_TCHAR*)calloc(Bites+128,sizeof(_TCHAR));
}
-
I can't find any obvious bug in the generated code (tested 5.0/6.0/ARM/X86 with my default compiler options) - either because I don't see it, or I don't have enough information. Sometimes it can be harder to comment on a single function rather than a small C program that can be compiled an tested.
Using memcpy(strtmp,S,tmplen*sizeof(_TCHAR)) or wmemcpy(strtmp,S,tmplen) should give the same result.
You say it works when you remove *sizeof(_TCHAR) on Win32? Works how? Correct result? Just no crashing? Something else? Any more information you can provide will probably be helpful...
-
Hi Pelle,
the Win32 Unicode translates LEFT$("This_is_a_test", 4) to "This_is_" obviously not 4 chars
I guess the best I can do is the attached files.
Left_test1 - Win32 asci BAS & C Code
Left_test2 - PPC Bas & C Code
Left_test3 - Win32 unicode Bas & C Code
I have added the compiler options for each file to the top of the C files for clarity.
Ian
-
OK, if I understand things correctly this is what you want:
_TCHAR *left (_TCHAR *S, int length)
{
register int tmplen = _tcslen(S);
if(length<1) return BCX_TmpStr(1);
if(length<tmplen) tmplen=length;
_TCHAR *strtmp = BCX_TmpStr(tmplen);
return (_TCHAR*)_tmemcpy(strtmp,S,tmplen);
}
Depending on _UNICODE _tmemcpy will expand to either memcpy or wmemcpy, copying either tmplen char's or tmplen wchar_t's; you don't need the multiplication with sizeof(_TCHAR).
-
Pelle,
Ok, I found 1 problem, memcpy was not being translated to _tmemcpy in my PPC code, this was in Win32 unicode version.
but I still only get 1/2 the characters displayed on my PPC.
LEFT$("This_is_a_test", 4) displays "Th"
I did try "return (_TCHAR*)wmemcpy(strtmp,S,tmplen);" and I get
POLINK: error: Unresolved external symbol 'wmemcpy'.
Ian
-
Your test programs seems to be for Win32, so I can't recompile for PPC without errors.
Microsoft's runtime is used on PPC, not mine, and apparently it does not contain a wmemcpy function.
In Pelles C version 6.0, the compiler has an intrinsic form of the wmemcpy function (also for ARM). By adding the following (in a separate #include file - or at the beginning of the generated C file, before the first use of wmemcpy) it should work:
wchar_t * __cdecl wmemcpy(wchar_t * restrict, const wchar_t * restrict, size_t);
#pragma intrinsic(wmemcpy)
Another solution, that should work with both version 5 and 6 of Pelles C, would be to define your own wmemcpy function (in the generated C file):
inline wchar_t * __cdecl wmemcpy(wchar_t *s1, const wchar_t *s2, size_t n)
{
for (wchar_t *s = s1; n > 0; s++, s2++, n--)
*s = *s2;
return s1;
}
-
Thanks Pelle,
I used the inline version and it's working great.
I added it to an include file I normally use for all my PPC projects.
Ian
-
There is also crtce.lib, which was added to provide some missing functions (not found in the Microsoft runtime on Windows Mobile). I don't remember why wmemcpy is not in crtce.lib, perhaps I was hoping that Microsoft should add it, eventually. It's still missing, so I guess they won't.
What I will do is to add wmemchr, wmemcmp, wmemcpy, wmemmove, wmemset to crtce.lib in version 6.0; it will be the default (C) versions, not super-optimized assembly versions, but for strings within reasonable limits it shouldn't matter, I think...
-
What I will do is to add wmemchr, wmemcmp, wmemcpy, wmemmove, wmemset to crtce.lib in version 6.0; it will be the default (C) versions, not super-optimized assembly versions, but for strings within reasonable limits it shouldn't matter, I think...
Wow, Thanks again Pelle,.
Ian
-
Pelle,
I downloaded version 6.0 rc.2 hoping it would cure all the worlds woes :-)
Alas,
I commmented out the function you posted for wmemcpy earlier in this topic, but I get
POLINK: error: Unresolved external symbol 'wmemcpy'.
POLINK: error: Unresolved external symbol 'wmemset'.
I checked what I could and all seems fine in the include tchar and wchar.h files
I added crtce.lib to my POLINK command line and still no luck.
pocc -Tarm-coff -Zi -W1 -MT -Gd -Go -Ze -Zx -D_WINCE -D_WIN32_WCE=0x400 -DDEBUG -DARM -D_ARM_ -DUNICODE -D_UNICODE filename.c
polink -release -machine:arm -subsystem:windowsce,4.0 filename.obj -stack:0x10000,0x1000 -version:1.1 aygshell.lib coredll.lib corelibc.lib commctrl.lib crtce.lib
Is there file missing here?
Thanks for your latest release!!
Ian
-
Hmm... it looks OK, and if the only complain is at link time you are *probably* compiling correctly.
wmemcpy and wmemset are in crtce.lib (as of 6.0 RC2) - are you perhaps picking up the wrong version?! Since this "should" work, I don't have many ideas right now...
-
Thanks Pelle,
That was my problem, for some reason it was going back to 5.00, but it created a much larger problem with wmemset, but I just used the regular memset and it seems to work. It needs some testing.
Ian