Board index » delphi » Converting Strings to PChar type.......

Converting Strings to PChar type.......

Hello,

I have read a number of different posts, regarding this subject.

I was looking for the best way of converting a 'String' to a String of type 'PChar'.

The following appears to work:  "TargetPCharString := PChar(SourceString)"

But are there any restrictions using this simple method??
Will this method 'crash' under certain circumstances?

I've seen a number of posts regarding 'StrPLCopy'.
How would this work better than original 'PChar' (above example).

Any response / suggestions are appreciated,
Regards Sam.

 

Re:Converting Strings to PChar type.......


Interesting problem - what exactly does PChar do ?

From what I can see it is a bit ambivalent - it can be used as a
typecast and also for *copying* data.

I ran up a small test to illustrate this :

procedure TForm1.Button1Click(Sender: TObject);
Var
  S:String;
  P:PChar;
begin
  S := '12345' + #0 + ' once etc' ;
  P := PChar( S ) ;

  //S[9] := 'x' ;   // Remove to show copying
  ShowMessage(IntToStr(Integer(@S[1])) + ' '
               + IntToStr( Integer(PChar(S)) ) + ' '
               + P[8] + ' ' + S[9]
                ) ;

end;

This shows (unless I've got it completely wrong) that a Typecasting
does nothing to the String (or anything else) however an assignment
copies the whole lot across - including data after the #0

That's pretty logical as why should a PChar be an ASCIIZ string ?

StrPLCopy does much the same - but you have to explicitly tell it how
many bytes you want to take - and it is just a front for StrLCopy
which hunts for #0 and takes the minimum of what you say or the
occurrence of #0

I guess if you are working with 'raw' memory then use assignment, and
if you just want to grab an ASCIIZ string then use StrPLCopy.

On 22 Nov 2001 04:16:40 -0800, Samh...@yahoo.com (SamH) wrote:

Quote
>Hello,

>I have read a number of different posts, regarding this subject.

>I was looking for the best way of converting a 'String' to a String of type 'PChar'.

>The following appears to work:  "TargetPCharString := PChar(SourceString)"

>But are there any restrictions using this simple method??
>Will this method 'crash' under certain circumstances?

>I've seen a number of posts regarding 'StrPLCopy'.
>How would this work better than original 'PChar' (above example).

>Any response / suggestions are appreciated,
>Regards Sam.

Re:Converting Strings to PChar type.......


In 16-bit mode, a 'string' is stored with a length at position #0, and
up to 255 characters of data with no terminating zero-byte.

In 32-bit mode, a 'string' is stored as a reference-counted memory
object with a header "before" the string value.  The string proper is a
pointer to the start of the value, which always ends with a zero.  So a
'string' value may be typecast and used as a 'PChar' (Pointer To
Character [string]).

There are some caveats.  If you "assign" a string, Delphi may simply
increment the reference count on the current value and have both strings
point to the same value.  You can request your own private copy of the
string if you wish.

Therefore, don't "diddle with" the string value.  Don't alter its
bytes.  If you need to do that, get your own bytes.

As long as you are aware of the reference-counting mechanism and how
Delphi is managing the string pool, it works quite well.

Quote
>SamH wrote:

> Hello,

> I have read a number of different posts, regarding this subject.

> I was looking for the best way of converting a 'String' to a String of type 'PChar'.

> The following appears to work:  "TargetPCharString := PChar(SourceString)"

> But are there any restrictions using this simple method??
> Will this method 'crash' under certain circumstances?

> I've seen a number of posts regarding 'StrPLCopy'.
> How would this work better than original 'PChar' (above example).

----------------------------------------------------------------
Sundial Services :: Scottsdale, AZ (USA) :: (480) 946-8259
mailto:i...@sundialservices.com  (PGP public key available.)

- Show quoted text -

Quote
> Fast(!), automatic table-repair with two clicks of the mouse!
> ChimneySweep(R):  Release 4.0 is here!!
> http://www.sundialservices.com/products/chimneysweep

Re:Converting Strings to PChar type.......


This makes sense if you think of PChar as being exactly what it says, ie a
pointer to char. In being a pointer to anything makes it a bit unDelphish,
but IMO its real value is purely in connecting to other languages, esp C.

Thus you can call the API quite happily with the cast
var
    sAString: string;

begin
    APIFunction(PChar(sAString));

Although the Delphi string doesn't need to be null terminated to be used
correctly by the delphi compiler, never-the-less the default behaviour is to
null terminate it. Thus code dropped by a C compiler will take the address
passed as PChar and read-off the memory image a char at a time until it
encounters a null. So C programs can be securely  passed strings as direct
PChar casts.

The problem comes when you want to transfer back the other way. Handing back
a pointer to a null terminated string is insufficient for the string type to
operate correctly in the Delphi context. Delphi needs the string length to
be set, it really doesn't care about the null. Hence Jerry's comment that
you are OK provided you don't change the length of the string.

However, the expression StrLen(PChar(sAstring)) returns the length of the
string up to the first null, rather than its 'delphi' length, and the
expression
SetLength(sAString, StrLen(PChar(sAString))), sets the length of the Delphi
string so that it no looks to Delphi as it does to a C compiler.

An obvious caveat is that the string has to be large enough to take whatever
is being passed back. A well written API will provide a means of  handling
this, eg you pass it the allocated size of the string, and it makes sure it
doesn't overflow this limit.

Dave

Quote
J French <je...@iss.u-net.com> wrote in message

news:3bfd01ca.8535602@news.u-net.com...
Quote
> Interesting problem - what exactly does PChar do ?

> From what I can see it is a bit ambivalent - it can be used as a
> typecast and also for *copying* data.

> I ran up a small test to illustrate this :

> procedure TForm1.Button1Click(Sender: TObject);
> Var
>   S:String;
>   P:PChar;
> begin
>   S := '12345' + #0 + ' once etc' ;
>   P := PChar( S ) ;

>   file://S[9] := 'x' ;   // Remove to show copying
>   ShowMessage(IntToStr(Integer(@S[1])) + ' '
>                + IntToStr( Integer(PChar(S)) ) + ' '
>                + P[8] + ' ' + S[9]
>                 ) ;

> end;

> This shows (unless I've got it completely wrong) that a Typecasting
> does nothing to the String (or anything else) however an assignment
> copies the whole lot across - including data after the #0

> That's pretty logical as why should a PChar be an ASCIIZ string ?

> StrPLCopy does much the same - but you have to explicitly tell it how
> many bytes you want to take - and it is just a front for StrLCopy
> which hunts for #0 and takes the minimum of what you say or the
> occurrence of #0

> I guess if you are working with 'raw' memory then use assignment, and
> if you just want to grab an ASCIIZ string then use StrPLCopy.

> On 22 Nov 2001 04:16:40 -0800, Samh...@yahoo.com (SamH) wrote:

> >Hello,

> >I have read a number of different posts, regarding this subject.

> >I was looking for the best way of converting a 'String' to a String of
type 'PChar'.

> >The following appears to work:  "TargetPCharString :=

PChar(SourceString)"

- Show quoted text -

Quote

> >But are there any restrictions using this simple method??
> >Will this method 'crash' under certain circumstances?

> >I've seen a number of posts regarding 'StrPLCopy'.
> >How would this work better than original 'PChar' (above example).

> >Any response / suggestions are appreciated,
> >Regards Sam.

Re:Converting Strings to PChar type.......


In article <F3jL7.16446$li3.144...@ozemail.com.au>, "David Reeve"

Quote
<drscienti...@powerup.com.au> writes:
>However, the expression StrLen(PChar(sAstring)) returns the length of the
>string up to the first null, rather than its 'delphi' length,

But isn't that the same as Length(string(sAString)), it seems to be. StrLen
provides the length only to the first #0.

Quote
> and the expression
> SetLength(sAString, StrLen(PChar(sAString))), sets the length of the Delphi
> string so that it no<w> looks to Delphi as it does to a C compiler.

That guarantees a reference count of 1 (if that is important) but doesn't
otherwise appear to do anything more than string() does.

Alan Lloyd
alangll...@aol.com

Re:Converting Strings to PChar type.......


Hmmm... the plot thickens.

I'm dubious that the cast of the string type to string does anything. If you
force a null into the middle of a string, as could well happen when a C dll
writes back to the delphi string, then the string retains its original
(wrong) length, but assignments such as  Label.Caption :=  MyString only
output the chars up to the inserted null. I guess this makes some sort of
sense since all outputs to the canvas must eventually go through the API
which is C based.

Delphi help indicates that you have to reset the string length as I
suggested. However, it also points out that if you use an array of char  the
resetting of length is automatic when the array is then assigned to a
string. Check out the following test....

var
  St: string;
  buf: array[0..50] of char;

// force a null into the midlle of a string
procedure TForm1.Button1Click(Sender: TObject);
begin
  St:='chars before the null'+' '+'chars after the null';
  St[22] := #0;

 Label1.Caption := IntToStr(Length(St));   // shows 42
 Label2.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
 Label3.Caption := St; file://displays first 21
 Label4.Caption := IntToStr(Length(string(St)));  file://shows 42

  SetLength(St, StrLen(PChar(St)));
 Label5.Caption := IntToStr(Length(St));   // shows 21
 Label6.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
end;

// force a null into the middle of a char array.
procedure TForm1.Button2Click(Sender: TObject);
begin
 buf := 'chars before the null'+' '+'chars after the null';
  buf[21] := #0;
  St := buf;

  Label1.Caption := IntToStr(Length(St));   // shows 21
 Label2.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
 Label3.Caption := St; file://displays first 21
 Label4.Caption := IntToStr(Length(string(St)));  file://shows 21

  SetLength(St, StrLen(PChar(St)));
 Label5.Caption := IntToStr(Length(St));   // shows 21
 Label6.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
end;

Quote
AlanGLLoyd <alangll...@aol.com> wrote in message

news:20011123053316.27263.00001386@nso-fe.aol.com...
Quote
> In article <F3jL7.16446$li3.144...@ozemail.com.au>, "David Reeve"
> <drscienti...@powerup.com.au> writes:

> >However, the expression StrLen(PChar(sAstring)) returns the length of the
> >string up to the first null, rather than its 'delphi' length,

> But isn't that the same as Length(string(sAString)), it seems to be.
StrLen
> provides the length only to the first #0.

> > and the expression
> > SetLength(sAString, StrLen(PChar(sAString))), sets the length of the
Delphi
> > string so that it no<w> looks to Delphi as it does to a C compiler.

> That guarantees a reference count of 1 (if that is important) but doesn't
> otherwise appear to do anything more than string() does.

> Alan Lloyd
> alangll...@aol.com

Re:Converting Strings to PChar type.......


Yes - the PChar to String conversion hunts for the #0

Another demo:

procedure TForm1.Button1Click(Sender: TObject);
Var
  S : String;
begin
  S := '123456789' ;
  S[8] := #0 ;
  S := String( PChar( S ) ) ;
  ShowMessage( S + ' len:'
               + IntToStr( Length( S ) ) ) ;
end;

On Sat, 24 Nov 2001 00:18:06 +1000, "David Reeve"

Quote
<drscienti...@powerup.com.au> wrote:
>Hmmm... the plot thickens.

>I'm dubious that the cast of the string type to string does anything. If you
>force a null into the middle of a string, as could well happen when a C dll
>writes back to the delphi string, then the string retains its original
>(wrong) length, but assignments such as  Label.Caption :=  MyString only
>output the chars up to the inserted null. I guess this makes some sort of
>sense since all outputs to the canvas must eventually go through the API
>which is C based.

>Delphi help indicates that you have to reset the string length as I
>suggested. However, it also points out that if you use an array of char  the
>resetting of length is automatic when the array is then assigned to a
>string. Check out the following test....

>var
>  St: string;
>  buf: array[0..50] of char;

>// force a null into the midlle of a string
>procedure TForm1.Button1Click(Sender: TObject);
>begin
>  St:='chars before the null'+' '+'chars after the null';
>  St[22] := #0;

> Label1.Caption := IntToStr(Length(St));   // shows 42
> Label2.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
> Label3.Caption := St; file://displays first 21
> Label4.Caption := IntToStr(Length(string(St)));  file://shows 42

>  SetLength(St, StrLen(PChar(St)));
> Label5.Caption := IntToStr(Length(St));   // shows 21
> Label6.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
>end;

>// force a null into the middle of a char array.
>procedure TForm1.Button2Click(Sender: TObject);
>begin
> buf := 'chars before the null'+' '+'chars after the null';
>  buf[21] := #0;
>  St := buf;

>  Label1.Caption := IntToStr(Length(St));   // shows 21
> Label2.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
> Label3.Caption := St; file://displays first 21
> Label4.Caption := IntToStr(Length(string(St)));  file://shows 21

>  SetLength(St, StrLen(PChar(St)));
> Label5.Caption := IntToStr(Length(St));   // shows 21
> Label6.Caption := IntToStr(StrLen(PChar(St)));  file://shows 21
>end;

>AlanGLLoyd <alangll...@aol.com> wrote in message
>news:20011123053316.27263.00001386@nso-fe.aol.com...
>> In article <F3jL7.16446$li3.144...@ozemail.com.au>, "David Reeve"
>> <drscienti...@powerup.com.au> writes:

>> >However, the expression StrLen(PChar(sAstring)) returns the length of the
>> >string up to the first null, rather than its 'delphi' length,

>> But isn't that the same as Length(string(sAString)), it seems to be.
>StrLen
>> provides the length only to the first #0.

>> > and the expression
>> > SetLength(sAString, StrLen(PChar(sAString))), sets the length of the
>Delphi
>> > string so that it no<w> looks to Delphi as it does to a C compiler.

>> That guarantees a reference count of 1 (if that is important) but doesn't
>> otherwise appear to do anything more than string() does.

>> Alan Lloyd
>> alangll...@aol.com

Re:Converting Strings to PChar type.......


On 22 Nov 2001 04:16:40 -0800, Samh...@yahoo.com (SamH) wrote:

Quote
>Hello,

>I have read a number of different posts, regarding this subject.

>I was looking for the best way of converting a 'String' to a String of type 'PChar'.

>The following appears to work:  "TargetPCharString := PChar(SourceString)"

>But are there any restrictions using this simple method??

Yes. There's a long section in the docs on when this typecast
is safe and when it is not.

Quote
>Will this method 'crash' under certain circumstances?

Yes. _Exactly_ what are you trying to do?

Quote
>I've seen a number of posts regarding 'StrPLCopy'.
>How would this work better than original 'PChar' (above example).

>Any response / suggestions are appreciated,
>Regards Sam.

David C. Ullrich

Re:Converting Strings to PChar type.......


On rereading this thread I see that we have covered the very real
possibility of not understanding what's going on when using the PChar cast,
but haven't touched upon  the specific  hazard associated with it.

The danger is that a nice neat cast like.........
myProcedure(PChar(SomeString))
does *not* increment the reference count of SomeString, and Somestring could
be garbage-collected, thereby leaving the pointer to char wild. Hence, the
need to explicitly copy the Delphi string to a null terminated version  in
those circumstance where it is not crystal clear that the Delphi string will
be in place when accessed by the pointer.

Dave

Quote
SamH <Samh...@yahoo.com> wrote in message

news:3feda359.0111220416.79cb2407@posting.google.com...
Quote
> Hello,

> I have read a number of different posts, regarding this subject.

> I was looking for the best way of converting a 'String' to a String of
type 'PChar'.

> The following appears to work:  "TargetPCharString := PChar(SourceString)"

> But are there any restrictions using this simple method??
> Will this method 'crash' under certain circumstances?

> I've seen a number of posts regarding 'StrPLCopy'.
> How would this work better than original 'PChar' (above example).

> Any response / suggestions are appreciated,
> Regards Sam.

Re:Converting Strings to PChar type.......


In article <k7ML7.17844$li3.185...@ozemail.com.au>, "David Reeve"

Quote
<drscienti...@powerup.com.au> writes:
>The danger is that a nice neat cast like.........
>myProcedure(PChar(SomeString))
>does *not* increment the reference count of SomeString, and Somestring could
>be garbage-collected, thereby leaving the pointer to char wild. Hence, the
>need to explicitly copy the Delphi string to a null terminated version  in
>those circumstance where it is not crystal clear that the Delphi string will
>be in place when accessed by the pointer.

This aspect is (Ithink) addressed and determined in OPLG (D3) page 4-10 (and
the corresponding help file entry on "Long String Types")...

"The lifetime of a pointer returned by a PChar or Pointer typecast depends on
the argument of the typecast. If the argument is a long string expression, the
pointer remains valid only within the statement in which the typecast is
performed. This essentially limits such a typecast to use only in parameter
expressions. If the argument is a long string variable, the pointer remains
valid until a new value is assigned to the variable, or until the variable goes
out of scope."

Alan Lloyd
alangll...@aol.com

Re:Converting Strings to PChar type.......


"David Reeve" <drscienti...@powerup.com.au> skrev i melding
news:k7ML7.17844$li3.185019@ozemail.com.au...

Quote
> On rereading this thread I see that we have covered the very real
> possibility of not understanding what's going on when using the PChar cast,
> but haven't touched upon  the specific  hazard associated with it.

> The danger is that a nice neat cast like.........
> myProcedure(PChar(SomeString))
> does *not* increment the reference count of SomeString, and Somestring
could
> be garbage-collected, thereby leaving the pointer to char wild. Hence, the
> need to explicitly copy the Delphi string to a null terminated version  in
> those circumstance where it is not crystal clear that the Delphi string
will
> be in place when accessed by the pointer.

I can't see much problems with this, as handling the PChar parameter in
myProcedure necessarily means copying the data anyway (it's a PChar, right =>
manual allocation needed ?). When the routine is blocking, and the parameter
is used only within the routine, it's no problem at all. If the value should
persist after routine completion, the parameter needs to be copied. The
problem is about understanding that both string and PChar types are really
pointer values, and relies upon dynamic allocation. I made a lot of errors
before this was "burned into my mind", but after that I haven't experienced
such problems.
--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorge@takethisaway_itte.no (remve the obvious)

Re:Converting Strings to PChar type.......


On Sat, 24 Nov 2001 22:17:16 +1000, "David Reeve"

Quote
<drscienti...@powerup.com.au> wrote:
>On rereading this thread I see that we have covered the very real
>possibility of not understanding what's going on when using the PChar cast,
>but haven't touched upon  the specific  hazard associated with it.

>The danger is that a nice neat cast like.........
>myProcedure(PChar(SomeString))
>does *not* increment the reference count of SomeString, and Somestring could
>be garbage-collected, thereby leaving the pointer to char wild. Hence, the
>need to explicitly copy the Delphi string to a null terminated version  in
>those circumstance where it is not crystal clear that the Delphi string will
>be in place when accessed by the pointer.

That's one of the things that can go wrong - there are others.
For example note the difference in behavior between

var a, b: string;
begin
  a:= 'cat';
  b:= a;
  b[1]:= 'd';
  showmessage(a);
  showmessage(b);
end;

and

var a, b: string;
begin
  a:= 'cat';
  b:= a;
  PChar(b)[0]:= 'd';
  showmessage(a);
  showmessage(b);
end;

When you assign a string to another it's just a pointer
that's copied, but when one string is modified then the
data is copied so the first string is not modified. But
if you modify the string through a cast to a PChar it's
different...

Quote
>Dave

>SamH <Samh...@yahoo.com> wrote in message
>news:3feda359.0111220416.79cb2407@posting.google.com...
>> Hello,

>> I have read a number of different posts, regarding this subject.

>> I was looking for the best way of converting a 'String' to a String of
>type 'PChar'.

>> The following appears to work:  "TargetPCharString := PChar(SourceString)"

>> But are there any restrictions using this simple method??
>> Will this method 'crash' under certain circumstances?

>> I've seen a number of posts regarding 'StrPLCopy'.
>> How would this work better than original 'PChar' (above example).

>> Any response / suggestions are appreciated,
>> Regards Sam.

David C. Ullrich

Re:Converting Strings to PChar type.......


Quote
Bj?rge S?ther <REMOVE_bsaether@THIS_online.no> wrote in message

news:wEbM7.3165$v05.60143@news1.oke.nextra.no...

Quote
> "David Reeve" <drscienti...@powerup.com.au> skrev i melding
> news:k7ML7.17844$li3.185019@ozemail.com.au...
> > On rereading this thread I see that we have covered the very real
> > possibility of not understanding what's going on when using the PChar
cast,
> > but haven't touched upon  the specific  hazard associated with it.

> > The danger is that a nice neat cast like.........
> > myProcedure(PChar(SomeString))
> > does *not* increment the reference count of SomeString, and Somestring
> could
> > be garbage-collected, thereby leaving the pointer to char wild. Hence,
the
> > need to explicitly copy the Delphi string to a null terminated version
in
> > those circumstance where it is not crystal clear that the Delphi string
> will
> > be in place when accessed by the pointer.

> I can't see much problems with this, as handling the PChar parameter in
> myProcedure necessarily means copying the data anyway (it's a PChar, right
=>
> manual allocation needed ?). When the routine is blocking, and the
parameter
> is used only within the routine, it's no problem at all. If the value
should
> persist after routine completion, the parameter needs to be copied.

The problem arises more from the circumstances that require you to use
PChar. There are not a lot of reasons to use it within a pure Delphi
environment (maybe as few as none?), but it is definitely required for
interfacing to 3rd part DLLs including the OS API. Thus you really don't
know quite how the third party function will use the pointer it is given.
For example, its quite possible it will simply holdonto the pointer, rather
than copy across the string...... in a C programming environment that would
be a pretty standard approach. Another possibility is that the intention is
for the DLL function to write back to the memory location indicated by the
pointer...... this is true of many API functions.

Your point that while the calling function is blocking, everything should be
OK is valid. Provided, as you say, you have the potential hazard burned into
you mind, then you will think about each and everytime you use the cast.

Dave

- Show quoted text -

Quote
> The
> problem is about understanding that both string and PChar types are really
> pointer values, and relies upon dynamic allocation. I made a lot of errors
> before this was "burned into my mind", but after that I haven't
experienced
> such problems.
> --
> Bjoerge Saether
> Consultant / Developer
> http://www.itte.no
> Asker, Norway
> bjorge@takethisaway_itte.no (remve the obvious)

Re:Converting Strings to PChar type.......


"David Reeve" <drscienti...@powerup.com.au> skrev i melding
news:w5fM7.34956$li3.227095@ozemail.com.au...

Quote

> Bj?rge S?ther <REMOVE_bsaether@THIS_online.no> wrote in message
> news:wEbM7.3165$v05.60143@news1.oke.nextra.no...
> > "David Reeve" <drscienti...@powerup.com.au> skrev i melding
> > news:k7ML7.17844$li3.185019@ozemail.com.au...
> > > On rereading this thread I see that we have covered the very real
> > > possibility of not understanding what's going on when using the PChar
> cast,
> > > but haven't touched upon  the specific  hazard associated with it.

> > > The danger is that a nice neat cast like.........
> > > myProcedure(PChar(SomeString))
> > > does *not* increment the reference count of SomeString, and Somestring
> > could
> > > be garbage-collected, thereby leaving the pointer to char wild. Hence,
> the
> > > need to explicitly copy the Delphi string to a null terminated version
> in
> > > those circumstance where it is not crystal clear that the Delphi string
> > will
> > > be in place when accessed by the pointer.

> > I can't see much problems with this, as handling the PChar parameter in
> > myProcedure necessarily means copying the data anyway (it's a PChar,
right
> =>
> > manual allocation needed ?). When the routine is blocking, and the
> parameter
> > is used only within the routine, it's no problem at all. If the value
> should
> > persist after routine completion, the parameter needs to be copied.

> The problem arises more from the circumstances that require you to use
> PChar. There are not a lot of reasons to use it within a pure Delphi
> environment (maybe as few as none?), but it is definitely required for
> interfacing to 3rd part DLLs including the OS API. Thus you really don't
> know quite how the third party function will use the pointer it is given.
> For example, its quite possible it will simply holdonto the pointer, rather
> than copy across the string...... in a C programming environment that would
> be a pretty standard approach. Another possibility is that the intention is
> for the DLL function to write back to the memory location indicated by the
> pointer...... this is true of many API functions.

If the called routine holds onto the pointer rather than copying the string,
this will cause trouble if you aren't aware of it, as you'd normally dispose
a PChar after use, too. No difference here...

Quote
> Your point that while the calling function is blocking, everything should
be
> OK is valid. Provided, as you say, you have the potential hazard burned
into
> you mind, then you will think about each and everytime you use the cast.

I learned this through working with PChars, not with strings. The same
trouble may arise with strings, too, but the main reason why casting a string
to a PChar may be dangerous is IMHO that you may do this without having the
faintest idea about string allocation / disposal....PChar or string.

--
Bjoerge Saether
Consultant / Developer
http://www.itte.no
Asker, Norway
bjorge@takethisaway_itte.no (remve the obvious)

Re:Converting Strings to PChar type.......


ullr...@math.okstate.edu (David C. Ullrich) wrote in message <news:3c013349.946163262@news>...

Quote
> On Sat, 24 Nov 2001 22:17:16 +1000, "David Reeve"
> <drscienti...@powerup.com.au> wrote:

> >On rereading this thread I see that we have covered the very real
> >possibility of not understanding what's going on when using the PChar cast,
> >but haven't touched upon  the specific  hazard associated with it.

> >The danger is that a nice neat cast like.........
> >myProcedure(PChar(SomeString))
> >does *not* increment the reference count of SomeString, and Somestring could
> >be garbage-collected, thereby leaving the pointer to char wild. Hence, the
> >need to explicitly copy the Delphi string to a null terminated version  in
> >those circumstance where it is not crystal clear that the Delphi string will
> >be in place when accessed by the pointer.

> That's one of the things that can go wrong - there are others.
> For example note the difference in behavior between

> var a, b: string;
> begin
>   a:= 'cat';
>   b:= a;
>   b[1]:= 'd';
>   showmessage(a);
>   showmessage(b);
> end;

> and

> var a, b: string;
> begin
>   a:= 'cat';
>   b:= a;
>   PChar(b)[0]:= 'd';
>   showmessage(a);
>   showmessage(b);
> end;

> When you assign a string to another it's just a pointer
> that's copied, but when one string is modified then the
> data is copied so the first string is not modified. But
> if you modify the string through a cast to a PChar it's
> different...

> >Dave

> >SamH <Samh...@yahoo.com> wrote in message
> >news:3feda359.0111220416.79cb2407@posting.google.com...
> >> Hello,

> >> I have read a number of different posts, regarding this subject.

> >> I was looking for the best way of converting a 'String' to a String of
>  type 'PChar'.

> >> The following appears to work:  "TargetPCharString := PChar(SourceString)"

> >> But are there any restrictions using this simple method??
> >> Will this method 'crash' under certain circumstances?

> >> I've seen a number of posts regarding 'StrPLCopy'.
> >> How would this work better than original 'PChar' (above example).

> >> Any response / suggestions are appreciated,
> >> Regards Sam.

> David C. Ullrich

To EVERYONE that added a Post to my original query....

A very big 'T H A N K Y O U' - It's nice to see such an enthusiastic response!
It is all (now) a lot clearer, regarding String conversions etc.

Thanks again,
Sam.  :)

Go to page: [1] [2]

Other Threads