DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: vic_168999
今日帖子: 7
在线用户: 13
导航: 论坛 -> 经典工具 斑竹:liumazi,ruralboy  
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 17:30:36
标题:
DELPHI Range Check Error错误解决 浏览:1338
加入我的收藏
楼主: 各位大佬:
    我今天碰到个怪事,软件编译运行突然报Range Check Error的错误,如下图所示

我搞了一天发现很多原来没有问题的模块,都会影响到这个错误报出来,包含PING IP的功能,带有TeeChar的图表模块等,我可以非常确定这些功能原来都是正常的

我现在重装了软件,换了台电脑都还是一样,问题依旧,实在找不到什么原因了,请教各位有什么绝招解决吗?
此帖子包含附件:
PNG 图像
大小:4.5K
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 tms2021 (TMS2021) ▲▲△△△ -
普通会员
2023/9/20 17:37:02
1楼: 访问超出范围了,看看索引是不是超了
----------------------------------------------
欢迎加入Delphi的QQ群:462884906
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 17:51:56
2楼: 应该不是,我现在多个模块都报这个错误,今天上午还全是没问题的
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 17:57:14
3楼: 下面这段代码就会引发这个报警,之前这些代码都是正常的,如果把这段代码注释掉就正常,当然还有很多其它模块也一样,原来都是好的代码,现在到处起火


procedure TFProcNG.WFTotalNG;
var
   a,b,c:Single;
begin
   SDate:=DateEdit1.Text + FrmMain.FirstT;
   EDate:=DateToStr(DateEdit2.Date + 1) + FrmMain.FirstT;

   WFTotalCDS.Close;
   WFTotalCDS.CommandText:='select sum(COMPLETE_QTY) as PNum from SWFTotal where PRD_DATE between '''+
   DateEdit1.Text +''' and '''+ DateEdit2.Text +''' and COMPANYTYPE = ''WF'' ';
   WFTotalCDS.Open;
   B:=WFTotalCDS.FieldByName('PNum').AsFloat;

   WFTotalCDS.Close;
   WFTotalCDS.CommandText:='select sum(ProcNG.Num) AS Num from ProcNG where (ProcNG.NDate between '''+ SDate +''' and '''+ EDate +''') and (Tester = ''外发厂'') ';
   WFTotalCDS.Open;
   A:=WFTotalCDS.FieldByName('Num').AsFloat;

   C:=(A*1.0)/(B*1.0)*1000000;
   Label8.Text:=FormatFloat('#,###,##0',C);
   label9.Text:='外发拦截不良率(PPM)'+#13;
   label9.text:=label9.Text + '<'+FloatToStr(A)+'-'+FloatToStr(B)+'>';
   if C > GetStandValues('外发拦截不良率') then
   begin
     Circle3.Stroke.Color:=999988999999;
   end else
   begin
     Circle3.Stroke.Color:=999939229999;
   end;
end;
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 421 (421) ★☆☆☆☆ -
盒子活跃会员
2023/9/20 18:25:21
4楼: 如果不是真的有溢出问题,应该是只在Debug下出现的,把编译选项Debug下的Range checking设置为false就行了
----------------------------------------------
-
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 18:33:41
5楼: 我设置了Range Check为False,但问题还是会有。

我发现围绕问题都是数据转换的问题,比如上面的代码:
Circle3.Stroke.Color:=999988999999;
如果改成下面这种方式就可以:
Circle3.Stroke.Color:=TAlphaColors.Red;

但其它一些我没有办法,比如:
FIPAddress := inet_addr(PAnsiChar(ansistring(HostIP)));
这一句也会报错。

而这些在原来都是可以正常编译的
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 421 (421) ★☆☆☆☆ -
盒子活跃会员
2023/9/20 18:57:19
6楼: 都不检查了怎么还会有这问题,Shift+F9强制重新编译一下
----------------------------------------------
-
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 19:11:15
7楼: 我改成Release就什么毛病都没了,想死的感觉
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 freecat (freecat) ★☆☆☆☆ -
盒子活跃会员
2023/9/20 21:07:07
8楼: {$R-}
----------------------------------------------
-
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/20 21:28:00
9楼: you can force a "CASTING" when using a type "not explicitly informed", like your "COLOR"...  or be,

--> it's expected a TAlphaColor type, BUT you use a "Int64" (big integer)

then, you would can use this:  THIS COMPILED WITH NOT WARNING IN 32bits
  Circle1.Stroke.Color := TAlphaColor(999988999999);

Note: try use a "range valid to integers"!!!

BUT.... 999988999999 is not a "valid integer range"!

  //2147483647  valid integer max!
  //999988999999

any way, you would can have a "overflow" using value "so big"!!!!
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/20 21:49:12
10楼: 非常感谢,我想应该是这个问题,目前改了的模块都好了
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/20 21:58:06
11楼: NOTE 0: the Delphi/Object Pascal, does the "inference" of type according with your value informed, sometimes you'll have a "warning" when doing some like this:


var
  a, b, x, z: integer;
begin
  a := 65535;
  b := 65535;
  //

  // x := 65535 * 65535; // [dcc32 Error] Unit1.pas(43): E2099 Overflow in conversion or arithmetic operation
  //  --> 4.294.836.225

  // OK = compile!
  x := a * 65535;
  x := 65535 * a;
  x := a * b;
end;

then, try use at least a "operand" typed to determine what will be the resulted
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/21 8:06:53
12楼: TO:emailx45

首先感谢您的指点,我的部分代码修改以后,已经没有问题了,下面这句如何修改呢

var
FIPAddress:DWORD;

FIPAddress := inet_addr(PAnsiChar(ansistring(HostIP)));

假定其中HostIP的值为192.168.1.5,还是会报RANGE CHECK ERROR

如果改成:FIPAddress := inet_addr(PAnsiChar(HostIP));
则代码无效

我用得是DELPHI 11
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/21 8:10:52
13楼: 整段代码是从网上获取的,如下:

function PingHost(HostIP: string): boolean;
type
  PIPOptionInformation = ^TIPOptionInformation;
  TIPOptionInformation = packed record
    TTL: Byte;
    TOS: Byte;
    Flags: Byte;
    OptionsSize: Byte;
    OptionsData: pchar;
  end;
  PIcmpEchoReply = ^TIcmpEchoReply;
  TIcmpEchoReply = packed record
    Address: DWORD;
    Status: DWORD;
    RTT: DWORD;
    DataSize: WORD;
    Reserved: WORD;
    Data: Pointer;
    Options: TIPOptionInformation;
  end;
  TIcmpCreateFile = function: THandle; stdcall;
  TIcmpCloseHandle = function(IcmpHandle: THandle): boolean; stdcall;
  TIcmpSendEcho = function(IcmpHandle: THandle; DestinationAddress: DWORD; RequestData: Pointer; RequestSize: WORD; RequestOptions: PIPOptionInformation; ReplyBuffer: Pointer; ReplySize: DWORD; Timeout: DWORD): DWORD; stdcall;
var
  hICMP: THandle;
  hICMPdll: THandle;
  IcmpCreateFile: TIcmpCreateFile;
  IcmpCloseHandle: TIcmpCloseHandle;
  IcmpSendEcho: TIcmpSendEcho;
  pIPE: PIcmpEchoReply; 
  FIPAddress: DWORD;
  FSize: DWORD;
  FTimeOut: DWORD;
  BufferSize: DWORD;
  pReqData, pRevData: pchar;
  MyString: string;
begin
  result := false;
  hICMPdll := LoadLibrary('icmp.dll');
  if hICMPdll = 0 then
    Exit;
  @IcmpCreateFile := GetProcAddress(hICMPdll, 'IcmpCreateFile');
  @IcmpCloseHandle := GetProcAddress(hICMPdll, 'IcmpCloseHandle');
  @IcmpSendEcho := GetProcAddress(hICMPdll, 'IcmpSendEcho');
  hICMP := IcmpCreateFile;
  if (hICMP = INVALID_HANDLE_VALUE) then Exit;
  //uses winsock;
  FIPAddress := inet_addr(PANSIChar(ansistring(HostIP))); //这一句有问题
  MyString := 'T'; //send data buffer
  pReqData := pchar(MyString);
  FSize := 40; //receive data buffer
  BufferSize := SizeOf(TIcmpEchoReply) + FSize;
  GetMem(pIPE, BufferSize);
  FillChar(pIPE^, SizeOf(pIPE^), 0);
  GetMem(pRevData, FSize);
  pIPE^.Data := pRevData;
  FTimeOut := 50; 
  try
    result := IcmpSendEcho(hICMP, FIPAddress, pReqData, Length(MyString), nil, pIPE, BufferSize, FTimeOut) > 0;
  finally
    IcmpCloseHandle(hICMP);
    FreeLibrary(hICMPdll);
    FreeMem(pRevData);
    FreeMem(pIPE);
  end;
end;
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/22 3:01:14
14楼: according with many info on internet, EXISTS A BUG IN A WinApi.WinSock.pas to INET_ADDR(...) function

That way, you need use "WinApi.WinSock2.pas" for better results!!!

try this:

uses
  Winapi.WinSock2;



// INADDR_ANY       = u_long($00000000);

procedure TForm1.Button1Click(Sender: TObject);
var
  LNetAddrResult: DWORD { 4294967295 }; // integer
  LArrIP        : TArray<PAnsiChar>;
  LResults      : string;
begin
  LArrIP := [        { }
    '0.0.0.0',       { }
  '0.0.0.1',         { }
  '1.1.1.1',         { }
  '127.0.0.0',       { }
  '127.0.0.1',       { }
  '192.0.0.0',       { }
  '192.0.0.1',       { }
  '192.0.0.251',     { }
  '192.1.1.1',       { }
  '192.168.100.55',  { }
  '224.0.0.0',       { }
  '224.0.0.1',       { }
  '224.0.0.251',     { }
  '224.1.1.1',       { }
  '240.0.0.0',       { }
  '240.0.0.1',       { }
  '240.0.0.251',     { }
  '240.1.1.1',       { }
  '255.1.1.1',       { }
  '255.255.255.0',   { }
  '255.255.255.1',   { }
  '255.255.255.255', { }
  '255.255.255.251'  { }
    ];
  //
  LResults := 'const INADDR_NONE = DWORD($FFFFFFFF); in Winapi.WinSock.pas... ' + slinebreak;
  LResults := LResults + 'DWORD max value: 4294967295' + slinebreak;
  //
  try
    for var MyIP in LArrIP do
      begin
        try
          LNetAddrResult := inet_addr(MyIP);
          //
          // Windows Server 2003: value ">255/empty/null" in some block "a.b.c.d"
          // WinXP and before: value empty = "INADDR_ANY", value null = "INADDR_NONE" in some block "a.b.c.d"

          if (LNetAddrResult = INADDR_NONE) or (LNetAddrResult = INADDR_ANY) then
          LResults := LResults + slinebreak + 'IP: ' + string(MyIP) + ', result = INADDR_NONE/INADDR_ANY'
          else
          LResults := LResults + slinebreak + 'IP: ' + string(MyIP) + ', result = ' + LNetAddrResult.ToString
        except
          on E: Exception do
          LResults := LResults + slinebreak + '--------> ' + string(MyIP) + ', Exception: ' + E.Message;
        end;
      end;
    //
  finally
    Memo1.Text := LResults;
  end;
end;
此帖子包含附件:
PNG 图像
大小:99.0K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/22 3:17:53
15楼: if your intention is send a "PING", you can use "IdIcmpClient" component INDY in your RAD 11, it's more easy:

1) put a "IdIcmpClient" component or create a on-the-fly by code 
2) define the properties...

procedure TForm1.Button2Click(Sender: TObject);
var
  LMyICMPClient: TIdIcmpClient;
begin
  LMyICMPClient := TIdIcmpClient.Create(nil);
  try
    LMyICMPClient.Name          := 'MyPING_INDY';
    LMyICMPClient.Host          := '127.0.0.1';
    LMyICMPClient.IPVersion      := TIdIPVersion.Id_IPv4;
    LMyICMPClient.Port          := 8080;
    LMyICMPClient.Protocol       := 1;
    LMyICMPClient.ProtocolIPv6   := 58;
    LMyICMPClient.PacketSize     := 32;
    LMyICMPClient.ReceiveTimeout := 5000;
    //
    LMyICMPClient.OnReply  := MyIdIcmpClientOnReply;
    LMyICMPClient.OnStatus := MyIdIcmpClientOnStatus;
    //
    LMyICMPClient.Ping('hello');
  finally
    LMyICMPClient.Free;
  end;
end;

procedure TForm1.MyIdIcmpClientOnReply(ASender: TComponent; const AReplyStatus: TReplyStatus);
begin
  Memo1.Lines.Add('Reply: ' + AReplyStatus.Msg);
end;

procedure TForm1.MyIdIcmpClientOnStatus(ASender: TObject; const AStatus: TIdStatus; const AStatusText: string);
begin
  Memo1.Lines.Add('Status: ' + AStatusText);
end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/22 13:32:31
16楼: To calculate the decimal address from a dotted string, perform the following calculation.
(first octet * 256³) + 
(second octet * 256²) + 
(third octet * 256¹) + 
(fourth octet * 256⁰)
=  
(first octet * 16777216) + 
(second octet * 65536) + 
(third octet * 256) + 
(fourth octet)
= (192 * 16777216) + (168 * 65536) + (1 * 256) + (5) = 3232235781
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 changfenglee (葫芦老四) ★☆☆☆☆ -
普通会员
2023/9/23 9:48:29
17楼: To:emailx45

使用WinSock方式进行PING,我的服务器IP是10.2.10.150,所以

FIPAddress := inet_addr(PAnsiChar(ansistring(HostIP)));

得到的数值是-17万多,已超出范围才会报Range Check Error错误。

另外使用IdIcmpClient方式在WIN10系统上没有问题,但在WIN7系统上会报错,因为我们公司的电脑全部加了域,并且收回了管理员权限,在WIN7上会报权限被阻止的错误,如下:
此帖子包含附件:
PNG 图像
大小:31.6K
----------------------------------------------
【个人签名】:玩了多年DELPHI,终于从菜鸟升级成老菜鸟
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/23 22:54:16
18楼: try use "IcmpSendEcho2" windows api directly 

NOTE: using "IcmpSendEcho" you needs say TimeOut value > 0

https://learn.microsoft.com/zh-cn/windows/win32/api/icmpapi/nf-icmpapi-icmpsendecho2?redirectedfrom=MSDN
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
作者:
男 emailx45 (emailx45) ▲▲▲▲△ -
普通会员
2023/9/23 22:56:55
19楼: by StackOverFlow post

TIMEOUT > 0

TranslateStringToIpAddress(strIP: String; var ipAddress); <-- it can fail to IP not usable, like 0.0.0.0

-------

Stack Overflow
Products
IcmpSendEcho (ping) fails on Windows 10
Asked 5 years, 1 month ago
Modified 5 years ago
Viewed 2k times
2

We have a legacy Delphi application which uses IcmpSendEcho (from iphlpapi.dll) to perform echo requests. As I understand it, this performs the same function as "ping" from the command prompt.

On Windows XP, the code below works fine. When the IPv4 address is correct the response is quick and if not error code 11010 (IP_REQ_TIMED_OUT) is returned as expected.

However, on my 32-bit Windows 10 machine, the error code is 87 (ERROR_INVALID_PARAMETER). I've carefully reviewed the Microsoft documentation for IcmpSendEcho and cannot see anything obvious that is wrong.

"ping 200.1.2.121" (the example IPv4 address I use in the code sample) works as expected from the command prompt in both XP and 10.

type
  PIpAddress = ^TIpAddress;
  TIpAddress = record
    case Integer of
        0: (S_un_b: TSunB);
        1: (S_un_w: TSunW);
        2: (S_addr: LongWord);
  end;
  IpAddress = TIpAddress;

// Functions imported from external DLLs
function IcmpCreateFile() : THandle; stdcall; external 'iphlpapi.dll';
function IcmpCloseHandle(icmpHandle: THandle) : Boolean; stdcall; external 'iphlpapi.dll';
function IcmpSendEcho(IcmpHandle: THandle; ipDest: IpAddress;
    pRequestData: Pointer; nRequestSize: SmallInt; RequestOptions: Pointer;
    pReplyBuffer: Pointer; dwReplySize: DWORD; dwTimeout: DWORD) : DWORD; stdcall; external 'iphlpapi.dll';

procedure TranslateStringToIpAddress(strIP: String; var ipAddress);
var
    phe: PHostEnt;
    pac: PChar;
begin
    try
        phe := GetHostByName(PChar(strIP));
        if (Assigned(phe)) then
          begin
          pac := phe^.h_addr_list^;
          if (Assigned(pac)) then
          begin
          with TIpAddress(ipAddress).S_un_b do
          begin
          by1 := Byte(pac[0]);
          by2 := Byte(pac[1]);
          by3 := Byte(pac[2]);
          by4 := Byte(pac[3]);
          end;
          end
          else
          begin
          raise Exception.Create('Error getting IP from HostName');
          end;
          end
        else
          begin
          raise Exception.Create('Error getting HostName');
          end;
    except
        FillChar(ipAddress, SizeOf(ipAddress), #0);
    end;
end;

function Ping(strIpAddress : String) : Boolean;
const
    ICMP_ECHO_BUFFER = 128;     // Works as low as 28 on Windows XP (nothing works on Windows 10)
var
    address: IpAddress;
    dwReplies: DWORD;
    {$IFDEF DBG} dwErrorCode: DWORD; {$ENDIF}
    abyReplyBuffer: array[1..ICMP_ECHO_BUFFER] of BYTE;
begin
    // Use this function to determine if an IPv4 address can be reached
    Result := False;

    // "m_cache.hPingHandle" is generated earlier with a call to "IcmpCreateFile"
    if (m_cache.hPingHandle = INVALID_HANDLE_VALUE) then
        Exit;

    TranslateStringToIpAddress(strIpAddress, address);
    dwReplies := IcmpSendEcho(
        m_cache.hPingHandle, address, nil, 0, nil, @abyReplyBuffer, ICMP_ECHO_BUFFER, 0);

    {$IFDEF DBG}
    if (dwReplies = 0) then
        begin
        dwErrorCode := GetLastError();
        // dwErrorCode = 87 (ERROR_INVALID_PARAMETER, "The parameter is incorrect")
        Application.MessageBox(
          PAnsiChar(Format('WinError = %d', [dwErrorCode])), 'Ping failed', MB_ICONEXCLAMATION);
        end;
    {$ENDIF}

    // Success?
    Result := (dwReplies <> 0);
end;

// Usage elsewhere in the application...
Ping('200.1.2.121');    // Works on Windows XP, but fails on Windows 10
delphiwindows-10ipv4
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行78.125毫秒 RSS