如何在 Pascal 中获取 IP 地址
我在尝试查看 IP 地址并在消息框中显示时遇到这两个错误 错误
如下所示
[dcc32 错误] Unit1.pas(38): E2010 不兼容的类型:“PAnsiChar”和 'PWideChar' =>错误1
和
[dcc32 错误] Unit1.pas(40): E2010 不兼容的类型:“string”和 '字节数组[1..1024]' =>错误2
我可以在 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(缓冲区)上给我错误
代码现在看起来像这样
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.
Edit2
我的代码看起来像现在这个
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.
i am getting these two Errors trying to view IP address and show in a messagebox
Error looks like this
[dcc32 Error] Unit1.pas(38): E2010 Incompatible types: 'PAnsiChar' and
'PWideChar' => Error1
and
[dcc32 Error] Unit1.pas(40): E2010 Incompatible types: 'string' and
'array[1..1024] of Byte' => Error2
I could do this in C/C++ but i wanted to try something new in Delphi
My source code Looks like this
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.
Please what am I doing wrongly?
Edit
Okay, InternetOpenUrl
Worked,however , it still gives me error on the showmessage(buffer)
Code looks like this now
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.
Edit2
My code Looks like this now
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
第一个错误发生是因为您调用了该函数的 AnsiChar 版本。
使用
InternetOpenUrl
而不是InternetOpenUrlA
。第二个发生在您期望的下面一行。 ShowMessage 需要一个
字符串
,而不是字节数组
。编辑:
要从字节数组中获取字符串并传递给 ShowMessage,您需要知道字节以什么编码发送。假设是 UTF-8,转换可以简单地完成:
编辑 2:
好吧,对于 XE8 你还需要做更多的工作。
The first error happens because you call the AnsiChar version of the function.
Use
InternetOpenUrl
instead ofInternetOpenUrlA
.The second happens in the line below you expect it. ShowMessage expects a
string
and not anarray of byte
.Edit:
To get a string out of your array of bytes to be passed to ShowMessage, you need to know in what encoding the bytes are sent. Assuming that is UTF-8, the conversion can simply be done with:
Edit 2:
OK, for XE8 you have to do a bit more work.
在 C/C++ 中,您通常使用 NUL 结尾的字符串 - 并自己分配存储空间来保存该字符串。这就是您在代码中使用 BYTE 数组所做的事情。
在 Delphi 中,
string
是一种本机类型,而不仅仅是指向 NUL 终止字符数据的指针。从您提供的错误消息来看,错误发生在对 ShowMessage 的调用上,而不是在对 InternetReadFile 的调用上。
您需要将字符串变量传递给 ShowMessage。
您可以尝试这样做:
有一些方法可以更紧凑地做到这一点,但作为最近从 C++ 转向主要使用 Delphi 的人,我认为以这种方式查看操作有助于理解两种语言之间的差异。
In C/C++ you typically use a NUL terminated string -and allocate the storage to hold that string yourself. This is what you have done in your code with the BYTE array.
In Delphi a
string
is a native type, not just a pointer to NUL terminated character data.From the Error message you provided the error happens on the call to ShowMessage, not on the call to InternetReadFile.
You need to pass a string variable to ShowMessage.
You could try this:
There are ways you can do this more compactly, but as someone who has moved from C++ to mainly using Delphi these days I think looking at the operation this way helps to understand the differences between the two languages.