Passing a Local Variable as a PChar

From Appmethod Topics
Jump to: navigation, search

Go Up to Working with Strings


Consider the case where you have a local string variable that you need to initialize by calling a function that takes a PChar. One approach is to create a local array of char and pass it to the function, then assign that variable to the string:

// assume FillBuffer is a predefined function
function FillBuffer(Value:Integer; Buf:PChar; Count:Integer):Integer
begin
  // …
end;
// assume MAX_SIZE is a predefined constant
var
  i: Integer;
  buf: array[0..MAX_SIZE] of char;
  S: string;
begin
  i := FillBuffer(0, buf, SizeOf(buf));// treats buf as a PChar
  S := buf;
  //statements
end;

This approach is useful if the size of the buffer is relatively small, since it is allocated on the stack. It is also safe, since the conversion between an array of char and a string is automatic. The Length of the string is automatically set to the right value after assigning buf to the string.

To eliminate the overhead of copying the buffer, you can cast the string to a PChar (if you are certain that the routine does not need the PChar to remain in memory). However, synchronizing the length of the string does not happen automatically, as it does when you assign an array of char to a string. You should reset the string Length so that it reflects the actual width of the string. If you are using a function that returns the number of bytes copied, you can do this safely with one line of code:

var
  S: string;
begin
  SetLength(S, MAX_SIZE);// when casting to a PChar, be sure the string is not empty
  SetLength(S, GetModuleFilename(0, PChar(S), Length(S)));
  // statements
end;

See Also