Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How convert null-terminated string to an AnsiString?

I have some code that compiles fine with D7 but fails with D2010. Obviously it is an Unicode issue:

The compile error is: E2251 Ambiguous overloaded call to 'StrPas'

Here is the whole procedure:

procedure GetVersionInfo;
type
  PLangCharSetInfo = ^TLangCharSetInfo;
  TLangCharSetInfo = record
    Lang: Word;
    CharSet: Word;
  end;
var
  FileName: array [0..260] of Char;
  SubBlock: array [0..255] of Char;
  VerHandle: Cardinal;
  Size: Word;
  Buffer: Pointer;
  Data: Pointer;
  DataLen: LongWord;
  LangCharSetInfo: PLangCharSetInfo;
  LangCharSetString: string;
begin
  LabelComments.Caption := 'No version information for this program is available!';
  {Get size and allocate buffer for VerInfo}
  if GetModuleFileName(hInstance, FileName, SizeOf(FileName)) > 0 then
  begin
    Size := GetFileVersionInfoSize(FileName, VerHandle);
    if Size > 0 then
    begin
      GetMem(Buffer, Size);
      try
        if GetFileVersionInfo(FileName, VerHandle, Size, Buffer) then
        begin
          {Query first language and that language blocks version info}
          if VerQueryValue(Buffer, '\VarFileInfo\Translation', Pointer(LangCharSetInfo), DataLen) then
          begin
            LangCharSetString := IntToHex(LangCharSetInfo^.Lang, 4) +
                                 IntToHex(LangCharSetInfo^.CharSet, 4);
            if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\ProductName'), Data, DataLen) then
            begin
              LabelProductName.Caption := StrPas(Data);
              Caption := LabelProductName.Caption;
            end;
            if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\FileVersion'), Data, DataLen) then
              LabelVersion.Caption := StrPas(Data);
            if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\LegalCopyright'), Data, DataLen) then
              LabelCopyright.Caption := StrPas(Data);
            if VerQueryValue(Buffer, StrPCopy(SubBlock, '\StringFileInfo\' + LangCharSetString + '\Comments'), Data, DataLen) then
              LabelComments.Caption := StrPas(Data);
          end;
        end;
      finally
        FreeMem(Buffer, Size);
      end;
    end
  end;
end;

The doc for StrPas says

function StrPas(const Str: PAnsiChar): AnsiString; overload;

This function is provided fasor backwards compatibility only. To convert a null-terminated string to an AnsiString or native Delphi language string, use a typecast or an signment.

So the question is should I remove all calls to StrPas ? The only way I make this to compile is to do a hardcast to PAnsi char like:

LabelProductName.Caption := StrPas(PAnsiChar(Data));
like image 890
Roland Bengtsson Avatar asked Sep 17 '25 22:09

Roland Bengtsson


1 Answers

StrPas has not been required since Delphi 1, since they changed the Delphi compiler to convert the string correctly without a function call. See: http://coding.derkeiler.com/Archive/Delphi/borland.public.delphi.language.objectpascal/2004-01/1793.html

So just assign it, as follows:

LabelProductName.Caption := PAnsiChar(Data);

And yes, you should remove all calls to StrPas. It can't help and can only get you in trouble in D2010.

like image 115
lkessler Avatar answered Sep 20 '25 10:09

lkessler