Newsgroups : Borland : borland.public.delphi.nativeapi.win32 : 2006 Oct : Pchars - just be safe, why not?
| Subject: | Pchars - just be safe, why not? |
| Posted by: | "L505" (delphingz505com) |
| Date: | Mon, 23 Oct 2006 00:54:48 |
When using ansistrings in our programs along with the windows API or other
API's, many times we come across the pchar casting situation. We don't have the
source code to the windows API, so we just assume things. Many people use
casting for certain windows API functions, because they think that the windows
API probably won't write to the pchar and it's fairly safe to do a pchar cast.
However, this is kind of a risky thing to be doing - because it makes noobs
think that programming with pchars is as simple as casts. Then when they get to
the functions that write to the pchar, the casting blows up their program. So
why not use functions that clearly explain what is going on instead of promoting
all this casting?
The other thing I see people doing are funny things like double casts in order
to force a copy..
(if my memory serves me right, some double cast trickery can force a copy, but I
no longer remember because I don't use trickery any more in my programs)
// stuff like this
s:= ansistring(pchar(s))
But why do that, and obfuscate code with casts galore? Why not just use a
function called PCharToAnsistring. And for the other way around, instead of
AnsiStringToPchar we call it NewPchar.
Comments? Any mistakes in the below functions?
unit pcharutils;
// newb never needs to see this unit, he just puts it in his uses clause
...
{ create a pchar copy of an ansistring (ensures a copy, unlike a cast)
returns false if memory not available }
function NewPchar(const s: string; out rslt: pchar): boolean;
var
L: integer;
begin
rslt:= '';
result:= false;
L:= length(s);
//try
getmem(rslt, L + 1); // plus one for null char
move(s[1], rslt[0], L);
rslt[L]:= #0; // null is L since zero based
result:= true;
//except
result:= false;
//end;
end;
// dispose pchar
procedure RidPChar(rslt: pchar);
begin
freemem(rslt);
end;
To use this in a program:
uses
pcharutils;
...
var
p: pchar;
s: string;
begin
s:= 'test test blab';
s:= s + s;
s:= s + 'test test';
{IN} {OUT}
newpchar(s, p);
SomeAPIFunction(p);
ridpchar(p);
readln;
end.
Above is NOT obfuscated. Clean and simple, especially for delphi noobs looking
over a guru's code.
That's a lot cleaner than doing it yourself each and every time:
var
p: pchar;
s: string;
begin
s:= 'test test blah';
s:= s + s;
s:= s + ' test test';
L:= length(s);
// newb needs to see this obfuscated junk
getmem(rslt, L + 1);
move(s[1], rslt[0], L);
rslt[L]:= #0;
SomeAPIFunction(p);
freemem(rslt);
readln;
end.
Above is obfuscated. especially hard to understand for delphi noobs looking over
a guru's code.