Implicit string cast from 'AnsiChar' to 'string'

This is the forum for miscellaneous technical/programming questions.

Moderator: 2ffat

Post Reply
Lena
BCBJ Master
BCBJ Master
Posts: 710
Joined: Sun Feb 06, 2011 1:28 pm

Implicit string cast from 'AnsiChar' to 'string'

Post by Lena »

Hi.
How to correctly remove warnings in an Android project?

Code: Select all

function CheckInet: boolean;
var
  aResp: IHTTPResponse;
  aHTTP: THTTPClient;
begin
  Result := false;
  aHTTP := THTTPClient.Create;
  try
    try
      aResp := aHTTP.Head('http://google.com');
      //Result := aResp.StatusCode < 400;
      Result := true;
    except
      Result := false;
    end;
  finally
    FreeAndNil(aHTTP);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);

var
  check :boolean;
  meta: MarshaledAString;
  p: Integer;
Begin

 check := CheckInet;

  If not check Then
  Begin
    ShowMessage('No internet connection.' + sLineBreak + 'Нет интернет соединения.');
    FloatAnimation1.Enabled := False;
    Viewport3D1.Visible := False;
    exit;
  End;

   BASS_StreamFree(str);
   str := BASS_StreamCreateURL(PChar('http://91.199.194.34:8000'), 0, BASS_UNICODE, nil, nil);
   //ShowMessage(IntToStr(BASS_ErrorGetCode));

  If BASS_ErrorGetCode = 0 Then
  Begin

     BASS_ChannelPlay(str, True);
     Viewport3D1.Visible := True;
     FloatAnimation1.Enabled := True;
     Text1.Text := '';
     meta := BASS_ChannelGetTags(str, BASS_TAG_META);
     p := 0;
     if(meta <> nil) then
         p := Pos('StreamTitle=', meta); //Warning
     if(p = 0) then
        Begin
         Text1.Text := 'No Name. Название не указано.';
         Exit;
        End;
       p := p + 13;
       Copy(meta, p, Pos(';', meta) - p - 1);   //Warning
       Text1.Text := meta; //Show name of song  //Warning
       //ShowMessage(IntToStr(p) + meta);
   End;
End;

[DCC Hint] UnitMain.pas(69): H2077 Value assigned to 'CheckInet' never used
[DCC Warning] UnitMain.pas(116): W1057 Implicit string cast from 'AnsiChar' to 'string'
[DCC Warning] UnitMain.pas(123): W1057 Implicit string cast from 'AnsiChar' to 'string'
[DCC Warning] UnitMain.pas(124): W1057 Implicit string cast from 'AnsiChar' to 'string'
rlebeau
BCBJ Author
BCBJ Author
Posts: 1726
Joined: Wed Jun 01, 2005 3:21 am
Location: California, USA
Contact:

Re: Implicit string cast from 'AnsiChar' to 'string'

Post by rlebeau »

BASS_ChannelGetTags() returns a null-terminated "const char*" pointer to 8bit character data, which would be PAnsiChar in Delphi (though you are using MarshaledAString for that on Android). You are implicitly converting that pointer as-is to UnicodeString when passing it to System.Pos(), System.Copy(), and Text1.Text, hence the 3 "Implicit string cast" warnings. Use the System.TMarshal class, in particular its ReadStringAsAnsi() or ReadStringAsUtf8() method, to convert the MarshaledAString data to a UnicodeString before processing it, eg:

Code: Select all

procedure TForm1.Button1Click(Sender: TObject);
var
  meta: MarshaledAString;
  metaPtr: TPtrWrapper;
  metaStr, songName: String;
  startPos, endPos: Integer;
begin
  // is this check really necessary? Why not just let BASS_StreamCreateURL() fail if there is no Internet connection?
  if not CheckInet then
  begin
    ShowMessage('No internet connection.' + sLineBreak + 'Нет интернет соединения.');
    FloatAnimation1.Enabled := False;
    Viewport3D1.Visible := False;
    Exit;
  end;

  BASS_StreamFree(str);
  str := BASS_StreamCreateURL(PChar('http://91.199.194.34:8000'), 0, BASS_UNICODE, nil, nil);
  //ShowMessage(IntToStr(BASS_ErrorGetCode));

  if str <> 0{BASS_ErrorGetCode = 0} then
  begin
    BASS_ChannelPlay(str, True);
    Viewport3D1.Visible := True;
    FloatAnimation1.Enabled := True;
    Text1.Text := '';
    meta := BASS_ChannelGetTags(str, BASS_TAG_META);
    if meta <> nil then
    begin
      metaPtr := TPtrWrapper.Create(meta);
      metaStr := TMarshal.ReadStringAsAnsi(metaPtr); // or ReadStringAsUtf8(), if needed
    end;
    startPos := Pos('StreamTitle=', metaStr);
    if startPos = 0 then
    begin
      Text1.Text := 'No Name. Название не указано.';
      Exit;
    end;
    Inc(startPos, 12);
    endPos := Pos(';', metaStr, startPos); // or StrUtils.PosEx()
    if endPos <> 0 then
      songName := Copy(metaStr, startPos, endPos - startPos)
    else
      songName := Copy(metaStr, startPos, MaxInt);
    Text1.Text := songName; //Show name of song
    //ShowMessage(IntToStr(startPos) + meta);
  end;
end;
Remy Lebeau (TeamB)
Lebeau Software
Lena
BCBJ Master
BCBJ Master
Posts: 710
Joined: Sun Feb 06, 2011 1:28 pm

Re: Implicit string cast from 'AnsiChar' to 'string'

Post by Lena »

Hi, rlebeau.
Where is my mistake now? All Russian characters are unreadable. RAD10.4.1

Code: Select all

procedure DoMeta();
var
  meta: MarshaledAString;
  metaPtr: TPtrWrapper;
  metaStr, songName: String;
  startPos, endPos: Integer;

begin

  meta := BASS_ChannelGetTags(str, BASS_TAG_META);
  if (meta <> nil) then
  begin
      metaPtr := TPtrWrapper.Create(meta);
      metaStr := TMarshal.ReadStringAsAnsi(metaPtr); // or ReadStringAsUtf8(), if needed

    startPos := Pos('StreamTitle=', metaStr);
    if startPos = 0 then
    begin
      TThread.ForceQueue(nil,
          procedure
          begin
            Form1.Text1.Text := 'No Name.';
            //Exit;
          end)
    end

    else
      begin

       Inc(startPos, 12);
       endPos := Pos(';', metaStr, startPos); // or StrUtils.PosEx()

       //StreamTitle='Solomun - Kackvogel';StreamUrl='DNAS/streamart?sid=1;
       //remove 'StreamTitle=' and all 'StreamUrl=DNAS...'

      if endPos <> 0 then
        songName := Copy(metaStr, startPos, endPos - startPos)
      else
        songName := Copy(metaStr, startPos, MaxInt);


        TThread.ForceQueue(nil,
            procedure
            begin
               Form1.Text1.Text := songName;
            end)

     end;


  end;


 end;

Lena
BCBJ Master
BCBJ Master
Posts: 710
Joined: Sun Feb 06, 2011 1:28 pm

Re: Implicit string cast from 'AnsiChar' to 'string'

Post by Lena »

Sorry I fix. Change to ReadStringAsUtf8.
Post Reply