嘿S.O!我在StackOverflow.com上发布了Stack Overflow问题。讽刺最好!
反正。我在我的SkypeReply事件处理程序上调用了这个程序,它被解雇了很多:
Procedure OnCategoryRename;
Var
CategoryID : Integer;
sCtgName : String;
Begin
if (AnsiContainsStr(pCommand.Reply,'GROUP')) and (AnsiContainsStr(pCommand.Reply,'DISPLAYNAME')) then
begin
sCtgName := pCommand.Reply;
Delete(sCtgName,1,Pos('GROUP',sCtgName)+5);
CategoryID := StrToInt(Trim(LeftStr(sCtgName,Pos(' ',sCtgName))));
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
ShowMessage(sCtgName);
end;
这样做的想法是循环访问我的Skype群组列表,以查看已重命名的群组。 AFAIK并不重要,因为我的S.O被追溯到这里
Function GetCategoryByID(ID : Integer):IGroup;
Var
I : Integer;
Category : IGroup;
Begin
// Make the default result nil
Result := nil;
// Loop thru the CUSTOM CATEGORIES of the ONLY SKYPE CONTROL used in this project
// (which 100% positive IS attached ;) )
for I := 1 to frmMain.Skype.CustomGroups.Count do
Begin
// The Category Variable
Category := frmMain.Skype.CustomGroups.Item[I];
// If the current category ID returned by the loop matches the passed ID
if Category.Id = ID then
begin
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
end;
End;
End;
当我在Result:= Category设置断点时;和单步,这两行一遍又一遍地执行!
当我在第一个代码段中注释掉 sCtgName := GetCategoryByID(CategoryID).DisplayName;
时,没有溢出,会显示一次该消息。但是,GetCategoryByID
是我写的一个函数,我也编写了一个类似的函数,它工作正常(GetCategoryByName),所以我不明白为什么它决定重复
// Return the Category as Result (IGroup)
Result := Category;
// Exit the function.
Exit;
一遍又一遍。
如果您需要更多信息,请不要犹豫!
编辑:以下是如何重现它:https://gist.github.com/813389
编辑:这是我的CallStack,按要求:
Edit2:更多信息:
感谢您的时间! - 杰夫
答案 0 :(得分:5)
确保编译项目时关闭“优化”,“堆栈帧”和“使用debug .dcu”,以获得最详细的callstack。然后发布你在这里遇到堆栈溢出时得到的callstack(如果你无法从中识别问题的性质)。
答案 1 :(得分:3)
堆栈溢出可能是由无休止的递归引起的。
编写包含事件处理程序的代码时,必须非常小心。 正如大卫所说,你可以做的一件事就是帮助你调试这个问题,而不是通过这样的调用。 F7进入通话。
您可以做的另一件事是在函数GetCategoryById的顶部放置一个断点。现在看看你的Call Stack。你看到堆栈中重复的名字了吗?这应该很清楚。
答案 2 :(得分:3)
您的问题中没有显示的内容: 你在这里发布的“OnCategoryRename”函数是一个从“TForm.Skype1Reply”回调调用的子函数。
要看到这一点,我必须点击你的github链接 - 但我认为这是你问题的重点。
我的猜测:
我认为快速而肮脏的解决方法是改变
sCtgName := GetCategoryByID(CategoryID).DisplayName; // Removing THIS line does not produce a Stack Overflow!
与
sCtgName := //find another way to get the new name, which you can probably get from your ICommand object
pCommand.Reply.ReadDataFromReplyAndGetNewDisplayName;
将来,我建议您发布此类问题的完整代码示例。