Как получить IP-адрес в Паскале

я получаю эти две ошибки, пытаясь просмотреть IP-адрес и показать в окне сообщения

Ошибка выглядит так

[dcc32 Error] Unit1.pas(38): E2010 Incompatible types: 'PAnsiChar' and 'PWideChar' => Error1

и

[dcc32 Error] Unit1.pas(40): E2010 Incompatible types: 'string' and 'array[1..1024] of Byte' => Error2

Я мог бы сделать это на C/C++, но хотел попробовать что-то новое в Delphi.

Мой исходный код выглядит так

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
  var
    hInet: HINTERNET;
    hFile: HINTERNET;
    buffer: array[1..1024] of byte;
    bytesRead: DWORD;
    url : String;

begin
  url := 'https://icanhazip.com';
  hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  hFile := InternetOpenUrlA(hInet, PChar(url), nil, 0, 0, 0); //Error 1
  InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead); // Error 2
  showmessage(buffer);

end;

end.

Пожалуйста, что я делаю не так?

Редактировать

Хорошо, InternetOpenUrl Сработало, однако все равно выдает ошибку в showmessage(buffer)

Код сейчас выглядит так

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
  var
    hInet: HINTERNET;
    hFile: HINTERNET;
    buffer: array[1..1024] of byte;
    bytesRead: DWORD;
    url : String;

begin
  url := 'https://icanhazip.com';
  hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  hFile := InternetOpenUrl(hInet, PChar(url), nil, 0, 0, 0);
  InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);
  showmessage(buffer);

end;

end.

Редактировать2

Мой код сейчас выглядит так

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Wininet, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
  var
    hInet: HINTERNET;
    hFile: HINTERNET;
    buffer: String;
    bytesRead: DWORD;
    url : String;
    szMessage : String;
    i : integer;


begin
  //url := 'https://icanhazip.com';
  hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  hFile := InternetOpenUrl(hInet, PChar('https://icanhazip.com'), nil, 0, 0, 0);
  InternetReadFile(hFile,@buffer,SizeOf(buffer),bytesRead);

  //showmessage(buffer);
  Label1.Caption := buffer;

end;

end.

Пожалуйста, добавьте версию Delphi, которую вы используете.

Uwe Raabe 16.03.2022 12:56
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
131
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Первая ошибка возникает из-за того, что вы вызываете версию функции AnsiChar.

Используйте InternetOpenUrl вместо InternetOpenUrlA.

Второе происходит в строке ниже, чем вы ожидаете. ПоказатьСообщение ожидает string, а не array of byte.

Редактировать: Чтобы получить строку из вашего массива байтов для передачи в ShowMessage, вам нужно знать, в какой кодировке отправляются байты. Предполагая, что это UTF-8, преобразование можно просто выполнить с помощью:

ShowMessage(TEncoding.UTF8.GetString(Slice(buffer, bytesRead)))

Редактировать 2: Хорошо, для XE8 вам нужно проделать немного больше работы.

procedure TForm1.Button1Click(Sender: TObject);
  var
    hInet: HINTERNET;
    hFile: HINTERNET;
    buffer: TBytes;
    bytesRead: DWORD;
    url : String;

begin
  url := 'https://icanhazip.com';
  hInet := InternetOpen(PChar(application.title),INTERNET_OPEN_TYPE_PRECONFIG,nil,nil,0);
  hFile := InternetOpenUrl(hInet, PChar(url), nil, 0, 0, 0);
  SetLength(buffer, 1024);
  InternetReadFile(hFile,@buffer[0],Length(buffer),bytesRead);
  showmessage(TEncoding.UTF8.GetString(buffer, 0, bytesRead));    
end;

спасибо Уве. InternetOpenUrl работал, теперь это showmessage(buffer), все еще дает мне ошибки

Keros 16.03.2022 13:05

лемме обновить код.

Keros 16.03.2022 13:05

изменение на строку возвращает нарушение прав доступа. Позвольте мне показать вам, как выглядит мой код на этот раз

Keros 16.03.2022 13:26

См. мое редактирование этого ответа для примера преобразования байтов в строку.

Uwe Raabe 16.03.2022 14:18

он возвращает это как ошибку, сэр [dcc32 Error] Unit1.pas(45): E2250 Нет перегруженной версии GetString, которую можно было бы вызвать с этими аргументами

Keros 16.03.2022 15:19

Вот почему я попросил версию Delphi, которую вы используете. Если ничего не указано, я всегда предполагаю самое последнее.

Uwe Raabe 16.03.2022 15:32

Delphi XE8 — это версия Delphi.

Keros 16.03.2022 15:37

Я добавил пример для XE8

Uwe Raabe 16.03.2022 17:28

В C/C++ вы обычно используете строку с завершением NUL и выделяете память для хранения этой строки самостоятельно. Это то, что вы сделали в своем коде с массивом BYTE.

В Delphi string — это нативный тип, а не просто указатель на символьные данные с нулевым завершением.

Из предоставленного вами сообщения об ошибке ошибка возникает при вызове ShowMessage, а не при вызове InternetReadFile.

Вам нужно передать строковую переменную в ShowMessage.

Вы можете попробовать это:

var
  szMessage: String;
  i: Integer;

  SetLength(szMessage, bytesread);
  for i =1 to bytesread do
    szMessage[i]:=buffer[i-1];
  ShowMessage(szMessage);

Есть способы сделать это более компактно, но как человек, который в наши дни перешел с C++ на использование в основном Delphi, я думаю, что такой взгляд на операцию помогает понять различия между двумя языками.

Другие вопросы по теме