function TYxCySms.SendEx(MobileNO: OleVariant; const SerialNum, Info,
UserID, PhoneNO: WideString): WideString;
var
I: Integer;
sPhone: array of PChar;
vRes : PChar;
begin
try
Result:='';
SetLength(sPhone,1);
for I:=0 to StrToInt(PhoneNO) do
begin
sPhone[0] := PChar(VarToStr(MobileNO[I]));
vRes := SendSMS(PChar(VarToStr(SN)),sPhone[0],PChar(VarToStr(Info)));
if vRes<>'1' then
begin
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
end
else
begin
with ASP_Exec,Parameters do
begin
Close;
ProcedureName := 'YxCySms.BP_SmsSend;1';
Refresh;
ParamByName('@iOperator').Value := UserID;
ParamByName('@vcSendMobile').Value := VarToStr(MobileNO[I]);
ParamByName('@vcInfo').Value := Info;
ExecProc;
end;
end;
end;
SetComplete;
except
ON E:Exception do
begin
SetAbort;
raise ERangeError.Create(E.Message);
end;
end;
end;这段代码出会出一个非常怪的问题
当:StrToInt(PhoneNO)>=1时没有任何问题!
当:StrToInt(PhoneNO)=0是就出会错误!而且用异常也不能茯得错误,用高度模式可得到错误如下:
access violation at 0x01013494:read of address 0xffffffff
在系统的“事情查看器(本地)”出现的错误如下:事件类型: 错误
事件来源: Application Error
事件种类: 无
事件 ID: 1000
日期: 2005-04-01
事件: 15:55:48
用户: N/A
计算机: YXCY_RANDOMREN
描述:
错误应用程序 dllhost.exe,版本 5.1.2600.0,错误模块 yxcysmsserver.dll,版本 1.0.0.0,错误地址 0x00003494。有关更多信息,请参阅在 http://go.microsoft.com/fwlink/events.asp 的帮助和支持中心。
数据:
0000: 41 70 70 6c 69 63 61 74 Applicat
0008: 69 6f 6e 20 46 61 69 6c ion Fail
0010: 75 72 65 20 20 64 6c 6c ure dll
0018: 68 6f 73 74 2e 65 78 65 host.exe
0020: 20 35 2e 31 2e 32 36 30 5.1.260
0028: 30 2e 30 20 69 6e 20 79 0.0 in y
0030: 78 63 79 73 6d 73 73 65 xcysmsse
0038: 72 76 65 72 2e 64 6c 6c rver.dll
0040: 20 31 2e 30 2e 30 2e 30 1.0.0.0
0048: 20 61 74 20 6f 66 66 73 at offs
0050: 65 74 20 30 30 30 30 33 et 00003
0058: 34 39 34 0d 0a 494.. 特求高人指点,谢谢!
UserID, PhoneNO: WideString): WideString;
var
I: Integer;
sPhone: array of PChar;
vRes : PChar;
begin
try
Result:='';
SetLength(sPhone,1);
for I:=0 to StrToInt(PhoneNO) do
begin
sPhone[0] := PChar(VarToStr(MobileNO[I]));
vRes := SendSMS(PChar(VarToStr(SN)),sPhone[0],PChar(VarToStr(Info)));
if vRes<>'1' then
begin
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
end
else
begin
with ASP_Exec,Parameters do
begin
Close;
ProcedureName := 'YxCySms.BP_SmsSend;1';
Refresh;
ParamByName('@iOperator').Value := UserID;
ParamByName('@vcSendMobile').Value := VarToStr(MobileNO[I]);
ParamByName('@vcInfo').Value := Info;
ExecProc;
end;
end;
end;
SetComplete;
except
ON E:Exception do
begin
SetAbort;
raise ERangeError.Create(E.Message);
end;
end;
end;这段代码出会出一个非常怪的问题
当:StrToInt(PhoneNO)>=1时没有任何问题!
当:StrToInt(PhoneNO)=0是就出会错误!而且用异常也不能茯得错误,用高度模式可得到错误如下:
access violation at 0x01013494:read of address 0xffffffff
在系统的“事情查看器(本地)”出现的错误如下:事件类型: 错误
事件来源: Application Error
事件种类: 无
事件 ID: 1000
日期: 2005-04-01
事件: 15:55:48
用户: N/A
计算机: YXCY_RANDOMREN
描述:
错误应用程序 dllhost.exe,版本 5.1.2600.0,错误模块 yxcysmsserver.dll,版本 1.0.0.0,错误地址 0x00003494。有关更多信息,请参阅在 http://go.microsoft.com/fwlink/events.asp 的帮助和支持中心。
数据:
0000: 41 70 70 6c 69 63 61 74 Applicat
0008: 69 6f 6e 20 46 61 69 6c ion Fail
0010: 75 72 65 20 20 64 6c 6c ure dll
0018: 68 6f 73 74 2e 65 78 65 host.exe
0020: 20 35 2e 31 2e 32 36 30 5.1.260
0028: 30 2e 30 20 69 6e 20 79 0.0 in y
0030: 78 63 79 73 6d 73 73 65 xcysmsse
0038: 72 76 65 72 2e 64 6c 6c rver.dll
0040: 20 31 2e 30 2e 30 2e 30 1.0.0.0
0048: 20 61 74 20 6f 66 66 73 at offs
0050: 65 74 20 30 30 30 30 33 et 00003
0058: 34 39 34 0d 0a 494.. 特求高人指点,谢谢!
解决方案 »
- 求助:利用 IdFTPServer 建立FTP服务器,谢谢!
- 为什么在D7下,常用的服务端RemoteDataModule+ADOConnection,客户端SocketConnection 取服务名在XE2下会取不到呢?
- 使用INDY POP3控件时收下来的PDF附件有时不正常
- 谁有DELPHI的例子
- 关于stringgrid的一个问题。
- dxdbinspect的用法
- 怎么样在程序中动态的为ACCESS中创建一个数据表格!!!!!
- 求救啊!关于Quickreport的奇怪问题。
- 怎么判断一个控件是不是在屏幕上显示?
- 纳闷??
- webbrowser找不到站点
- 如何写数据库访问程序 完成后 不须安装 单个文件就可以!
不知道为什么会产生异常,但是,像你这样写,不是多循环了一次吗?
var
j :integer;
begin
.
.
try
j=StrToInt(PhoneNO);
except
j=0;
end;for i=0 to j do
begin
end;
...end;
当StrToInt(PhoneNO)=1时
Unit 调用的过程或函数
MtsRdm TMtsDataModule.Deactivate (1)
Classes TComponent._Release (2)
VCLCom TVCLAutoObject.ObjQueryInterface (3)
ComObj TComObject.ObjRelease (4)
Classes TComponent._Release (5)
ComObj TComObject.ObjRelease (6)
然后程序就停在这里!
当StrToInt(PhoneNO)=0时
Unit 调用的过程或函数
MtsRdm TMtsDataModule.Deactivate (1)
Classes TComponent._Release (2)
VCLCom TVCLAutoObject.ObjQueryInterface (3)
ComObj TComObject.ObjRelease (4)
Classes TComponent._Release (5)
ComObj TComObject.ObjRelease (6)
System TObject.Free "在这里发生错误" (7)
各位大哥再帮忙看一下!
谢谢了!
不知道为什么会产生异常,但是,像你这样写,不是多循环了一次吗?
不会多循环的啦
其实PhoneNO是数组MobileNO: OleVariant的成员个数!
UserID, PhoneNO: WideString): WideString;
var
I: Integer;
sPhone: array of PChar;
vRes : PChar;
begin
try
Result:='';
SetLength(sPhone,1);
for I:=0 to StrToInt(PhoneNO) do //应该是这行的问题, PhoneNO的长度跟MobileNo的长度一致?
begin
sPhone[0] := PChar(VarToStr(MobileNO[I])); //这边可能会引起下标越界问题
vRes := SendSMS(PChar(VarToStr(SN)),sPhone[0],PChar(VarToStr(Info)));
if vRes<>'1' then
begin
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
end
else
begin
with ASP_Exec,Parameters do
begin
Close;
ProcedureName := 'YxCySms.BP_SmsSend;1';
Refresh;
ParamByName('@iOperator').Value := UserID;
ParamByName('@vcSendMobile').Value := VarToStr(MobileNO[I]);
ParamByName('@vcInfo').Value := Info;
ExecProc;
end;
end;
end;
SetComplete;
except
ON E:Exception do
begin
SetAbort;
raise ERangeError.Create(E.Message);
end;
end;
end;//另外肯定不会是TObject.Free的问题, 别再调进去了。
如果MobileNO: OleVariant的成员个数是0,那么sPhone[0] := PChar(VarToStr(MobileNO[I]));你又去访问MobileNO[0],这不是访问一个并不存在的对象吗?怎么会不出问题呢?另外,for I:=0 to StrToInt(PhoneNO) do...确实会多循环一次,应该改成:
for I:=0 to StrToInt(PhoneNO)-1 do...
这样保证不会再出现你的所谓的错误了!
MobileNO[0] 这样访问没有问题啊
能取出其中的值来啊!!
还有我要说明的是
无论StrToInt(PhoneNO)的值是多少,我的函数都是完整的按我想要的方式在执行!
比如StrToInt(PhoneNO)>=0 则这段
sPhone[0] := PChar(VarToStr(MobileNO[I]));
vRes := SendSMS(PChar(VarToStr(SN)),sPhone[0],PChar(VarToStr(Info)));
if vRes<>'1' then
begin
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
end
else
begin
with ASP_Exec,Parameters do
begin
Close;
ProcedureName := 'YxCySms.BP_SmsSend;1';
Refresh;
ParamByName('@iOperator').Value := UserID;
ParamByName('@vcSendMobile').Value := VarToStr(MobileNO[I]);
ParamByName('@vcInfo').Value := Info;
ExecProc;
end;
end;
代码执行1次
比如StrToInt(PhoneNO)>=N 则这段
sPhone[0] := PChar(VarToStr(MobileNO[I]));
vRes := SendSMS(PChar(VarToStr(SN)),sPhone[0],PChar(VarToStr(Info)));
if vRes<>'1' then
begin
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
end
else
begin
with ASP_Exec,Parameters do
begin
Close;
ProcedureName := 'YxCySms.BP_SmsSend;1';
Refresh;
ParamByName('@iOperator').Value := UserID;
ParamByName('@vcSendMobile').Value := VarToStr(MobileNO[I]);
ParamByName('@vcInfo').Value := Info;
ExecProc;
end;
end;
代码执行N+1次
然后再执行以下代码
SetComplete;
except
ON E:Exception do
begin
SetAbort;
raise ERangeError.Create(E.Message);
end;
end;
end;
并且都能成功执行到最的一个end;
(以上我是用断点测试了的,是这样执行的,绝对没问题!!)然后怪事说出来了!StrToInt(PhoneNO)=0时要出错!
我又设置断点进行了深度的调试。发现他的执行过程是这样的!
(执行到最后一个End,再按F8,他们的步骤执行如下!)
当StrToInt(PhoneNO)=1时
Unit单元 调用的过程或函数
MtsRdm TMtsDataModule.Deactivate (1)
Classes TComponent._Release (2)
VCLCom TVCLAutoObject.ObjQueryInterface (3)
ComObj TComObject.ObjRelease (4)
Classes TComponent._Release (5)
ComObj TComObject.ObjRelease (6)
然后程序就停在这里!
当StrToInt(PhoneNO)=0时
Unit 调用的过程或函数
MtsRdm TMtsDataModule.Deactivate (1)
Classes TComponent._Release (2)
VCLCom TVCLAutoObject.ObjQueryInterface (3)
ComObj TComObject.ObjRelease (4)
Classes TComponent._Release (5)
ComObj TComObject.ObjRelease (6)
System TObject.Free "在这里发生错误" (7)
各位大哥再帮忙看一下!
谢谢了!
如果MobileNO: OleVariant的成员个数是0,那么sPhone[0] := PChar(VarToStr(MobileNO[I]));你又去访问MobileNO[0],这不是访问一个并不存在的对象吗?怎么会不出问题呢?回:
PhoneNO是我在前台传上来的值,是这样取的 PhoneNO:=IntToStr(high(MobileNO)),这个应该不是成员个数,但我忘记怎么表达了,^_^ <MobileNO在前台是一个数组>
所以MobileNO[0],是没有问题的吧??我测试了,有值!并且是正确的!
function TYxCySms.SendEx(MobileNO: OleVariant; const SerialNum, Info,
UserID, PhoneNO: WideString): WideString;
var
vRes : PChar;
begin
try
Result:='';
vRes := SendSMS(PChar(VarToStr(SN)),PChar(1399054****),PChar(VarToStr(Info)));
if vRes<>'1' then
Result := Result+'<'+sPhone[0]+'>'+'Error:'+strpas(vRes);
SetComplete;
except
ON E:Exception do
begin
SetAbort;
raise ERangeError.Create(E.Message);
end;
end;
end;
这样的话,也是要出同样的错误!就和当StrToInt(PhoneNO)=0我错误一样
但我一直想不明白的是为什么当StrToInt(PhoneNO)>=1的时候又没有任何问题呢?
谢谢大家
如果问题解决,我决定再加100分!!
high是计算数组的边界的上届,如果数组下界为0,像你这样做是正确的~~~
但是,问题在于high使用在动态数组上有时会出现问题,例如,当数组成员数为0时,high可能返回1
感觉使用high不好,使用Length好一些你给出的调试数据感觉是在减少一个对象(应该是MobileNO)的引用计数,当PhoneNO为0的时候这个对象的引用计数减少到了0,结果要被销毁~~~销毁这个对象的时候出了问题,应该还是入口参数(MobileNO)有问题~~~前台先用Length测试一下 if length(MobileNO) =0 ,就不用再PhoneNO:=IntToStr(high(MobileNO))直接退出算了~~
我有减少了一个参数,但还是要出问题呢!
function TYxCySms.SendOne(const MobileNO, SerialNum, Info,
UserID: WideString): WideString;
var
vRes : PChar;
begin
try
Result:='';
vRes := SendSMS(PChar(VarToStr(SN)),PChar(VarToStr(MobileNO)),PChar(VarToStr(Info)));
if vRes<>'1' then
Result := Result+'<'+MobileNO+'>'+'Error:'+strpas(vRes);
SetComplete;
except
SetAbort;
Raise;
end;
end;
注:SendSMS是一个DLL中的函数,会不会是这个引起的呢?
谢谢!
try
Result:='';
vRes := SendSMS(PChar(VarToStr(SN)),PChar('1399054****'),PChar('测试单独发送'));
if vRes<>'1' then
Result := Result+'<1399054****>Error:'+strpas(vRes);
SetComplete;
except
ON E:Exception do
begin
SetAbort;
Raise ERangeError.Create(E.Message);
end;
end;
将[I]改为[LOW()+I]
现在运行你的程序,记下出现异常时崩溃地址,将这个地址减去 40100 结果比如说是 1234 ,在 .map 文件中搜索这个地址,没有的话就去掉末尾数字比如 123 ,再搜一下。看结果里最接近的,恩,就是这里引起崩溃的。