Board index » delphi » PChar(string)

PChar(string)

Doesnt PChar(..string..) work in Delphi 1? If not, what's instead?

 

Re:PChar(string)


On Sat, 02 Nov 1996 00:46:50 +0100, Jonatan Magnusson

Quote
<jona...@bastad.se> wrote:
>Doesnt PChar(..string..) work in Delphi 1? If not, what's instead?

By convention, a PChar is a pointer to a zero-terminated string. There
is no guarantee, however, that a D1 Pascal string has a zero byte at
its end. Instead, you need to use StrPLCopy (or its equivalent) to
copy a Pascal string to a character array.

If you just need to cast a Pascal string to a PChar, say, for a
Windows API call, it is simplest to use a function that implements the
desired behavior. "Secrets of Delphi 2" shows how the function can
maintain a list of dynamically allocated PChars. You can cast any
string to a PChar simply by calling StrToPChar, and the function takes
care of the rest.

In D2, the StrToPChar function just typecasts the string to PChar, and
the compiler takes care of the details. By using StrToPChar, one can
write code that is more easily ported between D1 and D2.

--
Ray Lischner, Tempest Software, Inc., Corvallis, Oregon, USA
Author of Secrets of Delphi 2 (http://www.tempest-sw.com/secrets/)

Re:PChar(string)


If you're asking how to convert a Pascal string to a PChar then you do it
by:

StrPCopy(PChar,String)

Where PChar is the name of the PChar variable (or an array of Char) that
you want to end up with the data and String is the Pascal style string you
want to convert.

--
Dale Merrick
dmerr...@vci.net (home)
dalm...@atlasvanlines.com (work)

Re:PChar(string)


Quote
Jonatan Magnusson wrote:

> Doesnt PChar(..string..) work in Delphi 1? If not, what's instead?

        The official right way is StrPCopy (etc). The fast cheap easy
dangerous(!) way is PChar(@theString[1]) . (If you're going to do that and
send the result to a PChar function you need to insert a #0 at the end
of the string.)

        In D1 a string is not "just a pointer" as it is in D2, so the
typecast PChar(AString) can't work. The typecast PChar(@AString) is
"valid" but it doesn't do what you want - it will give you a PChar
pointing to the length byte at the start of the string (the length
byte of AString is AString[0]).

--
David Ullrich

?his ?s ?avid ?llrich's ?ig ?ile
(Someone undeleted it for me...)

Re:PChar(string)


On 2 Nov 1996 20:15:55 GMT, "Dale Merrick" <dmerr...@vci.net> wrote:

Quote
>If you're asking how to convert a Pascal string to a PChar then you do it
>by:

>StrPCopy(PChar,String)

>Where PChar is the name of the PChar variable (or an array of Char) that
>you want to end up with the data and String is the Pascal style string you
>want to convert.

For most uses, I recommend StrPLCopy instead of StrPCopy. The
difference is that StrPLCopy checks the length of the string it is
copying, which can prevent errors caused by running off the end of the
character array. This is a common problem in C programming, and it
would be shame to bring the problems of C into Pascal.
--
Ray Lischner, Tempest Software, Inc., Corvallis, Oregon, USA
Author of Secrets of Delphi 2 (http://www.tempest-sw.com/secrets/)

Re:PChar(string)


Quote
David Ullrich wrote:

> Jonatan Magnusson wrote:

> > Doesnt PChar(..string..) work in Delphi 1? If not, what's instead?

>         The official right way is StrPCopy (etc). The fast cheap easy
> dangerous(!) way is PChar(@theString[1]) . (If you're going to do that and
> send the result to a PChar function you need to insert a #0 at the end
> of the string.)

>         In D1 a string is not "just a pointer" as it is in D2, so the
> typecast PChar(AString) can't work. The typecast PChar(@AString) is
> "valid" but it doesn't do what you want - it will give you a PChar
> pointing to the length byte at the start of the string (the length
> byte of AString is AString[0]).

> --
> David Ullrich

> ?his ?s ?avid ?llrich's ?ig ?ile
> (Someone undeleted it for me...)

Be careful about this. A PChar in Delphi is not "just a pointer" either.
PChar's have a 2 byte length descriptor in bytes [-1] and [-2], which
may give spurious results if you try passing PChar(@theString[1]) to some
of the length checking routines. No problem of course if you pass it to
a C routine in a DLL.

- Soren

Re:PChar(string)


Quote
S?ren Turin wrote:

> David Ullrich wrote:

> > Jonatan Magnusson wrote:

> > > Doesnt PChar(..string..) work in Delphi 1? If not, what's instead?

> >         The official right way is StrPCopy (etc). The fast cheap easy
> > dangerous(!) way is PChar(@theString[1]) . (If you're going to do that and
> > send the result to a PChar function you need to insert a #0 at the end
> > of the string.)

> >         In D1 a string is not "just a pointer" as it is in D2, so the
> > typecast PChar(AString) can't work. The typecast PChar(@AString) is
> > "valid" but it doesn't do what you want - it will give you a PChar
> > pointing to the length byte at the start of the string (the length
> > byte of AString is AString[0]).

> > --
> > David Ullrich

> > ?his ?s ?avid ?llrich's ?ig ?ile
> > (Someone undeleted it for me...)

> Be careful about this. A PChar in Delphi is not "just a pointer" either.
> PChar's have a 2 byte length descriptor in bytes [-1] and [-2], which
> may give spurious results if you try passing PChar(@theString[1]) to some
> of the length checking routines. No problem of course if you pass it to
> a C routine in a DLL.

        Really? This is the first I've heard of this. Which PChar routines
use this information at the start? The code below would appear to indicate
that StrLen figures out the length by looking for the first null, as I
thought.

        (Um, I certainly believe that StrAlloc puts length information
somewhere and StrDispose looks at that to decide how much memory to free.
But that's a memory allocation issue, not length checking - it would
clearly be a _bad_ idea for StrDispose to determine the length by looking
for a null, since that that would mean you could orphan memory by
modifying the _contents_ of a buffer. If we're using the address of the
first character in a string as a PChar this does not come up, because
we're not allocating memory for the PChar, it's already been allocated
for the string. The only time you're supposed to call StrDispose is
after a StrAlloc (or maybe after some other PCharAllocation function).)

        Try this:

procedure TForm1.Button1Click(Sender: TObject);
var x:array[0..10] of word; j:integer;
begin
for j:=0 to 9 do x[j]:=$0101;
x[10]:=0;
ShowMessage(inttostr(StrLen(PChar(@x))));
ShowMessage(inttostr(StrLen(PChar(@x[5]))));
end;

        Looks to me like PChars are in fact handled as _null-terminated_
strings, as advertised.

--
David Ullrich

?his ?s ?avid ?llrich's ?ig ?ile
(Someone undeleted it for me...)

Other Threads